' Gambas module file

' Copyright(C) 2011-2014, Michał Głowienka aka eloaders <eloaders@linux.pl>
'
' This program is free software; you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation; either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU General Public License for more details.
'
' You should have received a copy of the GNU General Public License
' along with this program. If not, see <http://www.gnu.org/licenses/>.

Public Logs As New Logger
Public device_model As String
Public device_vendor As String
Public mount_point As String
Public device_uuid As String
Public real_size As String
Public partition_size As String
Public filesystem_type As String
Public mount_widtch As String
Public device_rev As String
Public max_sectors As String
Public device_state As String
Public modalias As String
Public check_swap As String
Public removable As String
Public ext_range As String
Public range As String
Public add_random As String
Public discard_granularity As String
Public discard_max_bytes As String
Public discard_zeroes_data As String
Public hw_sector_size As String
Public max_hw_sectors_kb As String
Public max_sectors_kb As String
Public max_segments As String
Public max_segment_size As String
Public read_ahead_kb As String
Public scheduler As String
Public max_ratio As String
Public min_ratio As String
Public stable_pages_required As String
Public logical_block_size As String ' logical_block_size
Public iostats As String 'iostats
Public minimum_io_size As String ' minimum_io_size
Public nomerges As String ' nomerges
Public nr_requests As String ' nr_requests
Public optimal_io_size As String ' optimal_io_size
Public physical_block_size As String ' physical_block_size
Public rotational As String ' rotational
Public rq_affinity As String ' rq_affinity
Public CONNECTED_PORT As String
Public Logical_Size As String
Public hw_sata_spd_limit As String
Public sata_spd As String
Public sata_spd_limit As String
Public SATA_PIC As Picture
Public USB_PIC As Picture
Public USB_SPEED As String
Public USB_VERSION As String
Public USB_BMAXPOWER As String

Function _inits()
  Dim Avail_HDD As Integer 
  Logs("Add Drives to ComboBox", Logger.Info)
  Finfosys.ComboBox4.Clear
  For Avail_HDD = 1 To Dir("/sys/block/", "sd*").Count
   Finfosys.ComboBox4.Add(Dir("/sys/block/", "sd*")[Avail_HDD - 1])
  Next
  For Avail_HDD = 1 To Dir("/sys/block/", "sr*").Count
   Finfosys.ComboBox4.Add(Dir("/sys/block/", "sr*")[Avail_HDD - 1])
  Next
End

Function _init_2()
  Dim count As Integer
  Logs("Add Drives to ComboBox..", Logger.Info)
  Finfosys.ComboBox3.Clear
  For count = 1 To Dir("/sys/block/" & Finfosys.ComboBox4.Text & "", "sd*").Count
   Finfosys.ComboBox3.Add(Dir("/sys/block/" & Finfosys.ComboBox4.Text & "", "" & Left$(Finfosys.ComboBox4.Text, - 1) & "*")[count - 1])
  Next
  
  For count = 1 To Dir("/sys/block/" & Finfosys.ComboBox4.Text & "", "sr*").Count
   Finfosys.ComboBox3.Add(Dir("/sys/block/" & Finfosys.ComboBox4.Text & "", "" & Left$(Finfosys.ComboBox4.Text, - 1) & "*")[count - 1])
  Next
  Finfosys.ComboBox3.Index = 0
End

Public Sub get_informations()
  Dim FREE_SPACE As String
  Dim Used As Float
  Dim SIZE_W As Float
  Dim SIZE_W_FREE As Float
  Logs("Deleting data from variables", Logger.Info)
   SETNULL()
  Logs("Get informations of Drives", Logger.Info)
  Try device_model = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/device/model"), "\n", "")
  Try device_vendor = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/device/vendor"), "\n", "")
  Try device_rev = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/device/rev"), "\n", "")
  Try max_sectors = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/device/max_sectors"), "\n", "")
  Try device_state = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/device/state"), "\n", "")
  Try modalias = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/device/modalias"), "\n", "")
  Try removable = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/removable"), "\n", "")
  Try ext_range = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/ext_range"), "\n", "")
  Try range = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/range"), "\n", "")
  Try add_random = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/add_random"), "\n", "")
  Try discard_granularity = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/discard_granularity"), "\n", "")
  Try discard_max_bytes = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/discard_max_bytes"), "\n", "")
  Try discard_zeroes_data = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/discard_zeroes_data"), "\n", "")
  Try hw_sector_size = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/hw_sector_size"), "\n", "")
  Try iostats = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/iostats"), "\n", "")
  Try logical_block_size = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/logical_block_size"), "\n", "")
  Try max_hw_sectors_kb = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/max_hw_sectors_kb"), "\n", "")
  Try max_sectors_kb = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/max_sectors_kb"), "\n", "")
  Try max_segments = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/max_segments"), "\n", "")
  Try max_segment_size = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/max_segment_size"), "\n", "")
  Try minimum_io_size = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/minimum_io_size"), "\n", "")
  Try nomerges = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/nomerges"), "\n", "")
  Try nr_requests = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/nr_requests"), "\n", "")
  Try optimal_io_size = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/optimal_io_size"), "\n", "")
  Try physical_block_size = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/physical_block_size"), "\n", "")
  Try read_ahead_kb = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/read_ahead_kb"), "\n", "")
  
  Try scheduler = Schedule(CString(Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/scheduler"), "\n", "")))
  
  Try rotational = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/rotational"), "\n", "")
  Try rq_affinity = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/queue/rq_affinity"), "\n", "")
  Try Logical_Size = CalculateLOGICAL(CFloat(Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/size"), "\n", "")))
  Try partition_size = CalculateSIZE(CLong(Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/" & Finfosys.ComboBox3.Text & "/size"), "\n", "")), True)
  Try real_size = CalculateSIZE(CLong(Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/size"), "\n", "")), True)
  Try max_ratio = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/bdi/max_ratio"), "\n", "")
  Try min_ratio = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/bdi/min_ratio"), "\n", "")
  Try stable_pages_required = Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/bdi/stable_pages_required"), "\n", "")

  Logs("Get informations of Drives Done", Logger.Info)
  disks()
   mount_point = Replace(mount_point, "\\040", " ")
   FREE_SPACE = Null
   Try FREE_SPACE = CalculateFreeSpace(Dfree(mount_point), True)
   Finfosys.Label248.Text = "Free:  " & FREE_SPACE
   Finfosys.ProgressBar2.Value = 0
   'Begins calculations of used space on device/partition
   Used = 0
   SIZE_W = 0
   SIZE_W_FREE = 0
   Try SIZE_W = CFloat(CalculateSIZE(CFloat(Replace(File.Load("/sys/block/" & Finfosys.ComboBox4.Text & "/" & Finfosys.ComboBox3.Text & "/size"), "\n", ""))))
   Try SIZE_W_FREE = CFloat(CalculateFreeSpace(CFloat(Dfree(mount_point))))
   Try Used = (SIZE_W - SIZE_W_FREE)
   If Used > 1 And SIZE_W > 1 Then
    Try Finfosys.ProgressBar2.Value = Used / SIZE_W
   Else 
    Try Finfosys.ProgressBar2.Value = 0 / 10
   Endif
   If Used = SIZE_W Then
    Try Finfosys.ProgressBar2.Value = 0 / 10
   Endif
   
   If check_swap Like "*" & Finfosys.ComboBox3.Text & "*" Then
    Finfosys.Label248.Text = "Free:  " & CString(SWAP_FREE())
   Endif
End

Function Schedule(sched As String) As String
 Select Case sched
  Case Like "*\\[noop\\]*"
   Return "noop"
  Case Like "*\\[deadline\\]*"
   Return "deadline"
  Case Like "*\\[cfq\\]*"
   Return "cfq"
  Case Like "*\\[bfq\\]*"
   Return "bfq"
  Case Like "*none*"
   If Exist("/sys/block/" & Finfosys.ComboBox4.Text & "/mq") Then
    Return "blk-mq"
   Else
    Return "none"
   Endif
 End Select
End


Function CalculateFreeSpace(Size As Float, Optional ReturnIn As Boolean) As String
  Dim REAL_SIZE_BYTES As Float
  Dim REAL_SIZE_KIB As Float
  Dim REAL_SIZE_MB As Float
  Dim REAL_SIZE_GB As Float
  Dim iPos As Integer
  REAL_SIZE_BYTES = Size
  REAL_SIZE_KIB = (Size / 1024)
  REAL_SIZE_MB = (Size / 1024 / 1024)
  REAL_SIZE_GB = (Size / 1024 / 1024 / 1024)

  Inc iPos
  If CLong(REAL_SIZE_GB) > 0 Then
   
   iPos = InStr(CString(REAL_SIZE_GB), ".")
   If ReturnIn = True Then
   Return Left$(CString(REAL_SIZE_GB), iPos + 1) & " GB"
   Else
    Return REAL_SIZE_BYTES
   Endif
  Else If CLong(REAL_SIZE_MB) > 0 Then
   iPos = InStr(CString(REAL_SIZE_MB), ".")
   If ReturnIn = True Then
   Return Left$(CString(REAL_SIZE_MB), iPos + 1) & " MB"
   Else
     Return REAL_SIZE_BYTES
   Endif
  Else If CLong(REAL_SIZE_KIB) > 0 Then
   iPos = InStr(CString(REAL_SIZE_KIB), ".")
   If ReturnIn = True Then
   Return Left$(CString(REAL_SIZE_KIB), iPos + 1) & " KiB"
   Else
    Return REAL_SIZE_BYTES
   Endif
  Endif
  Dec iPos
End

Function CalculateLOGICAL(BlockSize As Float) As String
 Dim LOGICAL_SIZE0 As Float
 Dim LOGICAL_SIZE1 As Long
 Dim LOGICAL_SIZE2 As Float
 Dim LOGICAL_SIZE3 As Float
 Dim iPos As Integer
 LOGICAL_SIZE0 = (BlockSize * 512 / 1000 / 1000 / 1000)
 LOGICAL_SIZE1 = (BlockSize * 512 / 1000 / 1000)
 LOGICAL_SIZE2 = (BlockSize * 512 / 1000)
 LOGICAL_SIZE3 = (BlockSize * 512)
 If CLong(LOGICAL_SIZE0) > 0 Then
   iPos = InStr(CString(LOGICAL_SIZE0), ".")
   Return Left$(CString(LOGICAL_SIZE0), iPos + 1) & Space$(1) & "GB"
  Else If LOGICAL_SIZE1 > 0 Then
   iPos = InStr(CString(LOGICAL_SIZE1), ".")
   Return Left$(CString(LOGICAL_SIZE1), iPos + 1) & Space$(1) & "MB"
  Else If CLong(LOGICAL_SIZE2) > 0 Then
   iPos = InStr(CString(LOGICAL_SIZE2), ".")
   Return Left$(CString(LOGICAL_SIZE2), iPos + 1) & Space$(1) & "KiB"
  Else If CLong(LOGICAL_SIZE3) > 0 Then
   iPos = InStr(CString(LOGICAL_SIZE3), ".")
   Return Left$(CString(LOGICAL_SIZE3), iPos + 1) & Space$(1) & "Bytes"
  Else
   Return 0
 Endif
 
 
End

Function CalculateSIZE(BlockSize As Float, Optional ReturnIn As Boolean) As String
  Dim REAL_SIZE_BYTES As Float
  Dim REAL_SIZE_KIB As Float
  Dim REAL_SIZE_MB As Float
  Dim REAL_SIZE_GB As Float
  Dim iPos As Integer
  REAL_SIZE_GB = (BlockSize / 2 / 1024 / 1024)
  REAL_SIZE_MB = (BlockSize / 2 / 1024)
  REAL_SIZE_KIB = (BlockSize / 2)
  REAL_SIZE_BYTES = (BlockSize * 512)

  If CLong(REAL_SIZE_GB) > 0 Then
   iPos = InStr(CString(REAL_SIZE_GB), ".")
   If ReturnIn = True Then
   Return Left$(CString(REAL_SIZE_GB), iPos + 1) & Space$(1) & "GB"
   Else
    Return REAL_SIZE_BYTES
   Endif
  Else If CLong(REAL_SIZE_MB) > 0 Then
   If ReturnIn = True Then
   Return CLong(REAL_SIZE_MB) & Space$(1) & "MB"
   Else
    Return REAL_SIZE_BYTES
   Endif
  Else If CLong(REAL_SIZE_KIB) > 0 Then
   iPos = InStr(CString(REAL_SIZE_KIB), ".")
   If ReturnIn = True Then
   Return Left$(CString(REAL_SIZE_KIB), iPos + 1) & Space$(1) & "KiB"
   Else
    Return REAL_SIZE_BYTES
   Endif
  Else If CLong(REAL_SIZE_BYTES) > 0 Then
   iPos = InStr(CString(REAL_SIZE_BYTES), ".")
   If ReturnIn = True Then
   Return Left$(CString(REAL_SIZE_BYTES), iPos + 1) & Space$(1) & "Bytes"
   Else
    Return REAL_SIZE_BYTES
   Endif
  Endif

End

Public Sub disks()
  Dim i, i2 As Integer
  Dim MOUNTS_PROC As File
  Dim SWAPS_PROC As File
  Dim MountsLine As String
  Dim SwapsLine As String
  filesystem_type = Null
  mount_widtch = Null
  mount_point = Null
  device_uuid = Null
  
   If IsNull(Finfosys.ComboBox3.Text) = False Then
   For i = 0 To Dir("/dev/disk/by-uuid/", "*", gb.File).Count - 1
    With Stat("/dev/disk/by-uuid/" & Dir("/dev/disk/by-uuid/", "*")[i])
    If .Link Like "*" & Replace(Finfosys.ComboBox3.Text, " ", " ") & "*" Then
     device_uuid = Dir("/dev/disk/by-uuid/", "*")[i]
    Endif
    End With
   Next
   Endif
   
   If IsNull(Finfosys.ComboBox3.Text) = True Then
   For i = 0 To Dir("/dev/disk/by-uuid/", "*", gb.File).Count - 1
    With Stat("/dev/disk/by-uuid/" & Dir("/dev/disk/by-uuid/", "*")[i])
     If .Link Like "*" & Replace(Finfosys.ComboBox4.Text, " ", " ") & "*" Then
      device_uuid = Dir("/dev/disk/by-uuid/", "*")[i]
     Endif
    End With
   Next
   Endif
   
   If Access("/proc/mounts", gb.Read) = True Then
   MOUNTS_PROC = Open "/proc/mounts"
   For Each MountsLine In MOUNTS_PROC.Lines
    For i = 0 To Split(MountsLine, " ", "%%").Count - 1
     If IsNull(Finfosys.ComboBox3.Text) = False Then
      
      If Split(MountsLine, " ", "%%")[i] Like "*" & Finfosys.ComboBox3.Text & "*" Then
       mount_point = Split(MountsLine, " ", "%%")[1]
       filesystem_type = Split(MountsLine, " ", "%%")[2]
       mount_widtch = Split(MountsLine, " ", "%%")[3]
      Endif

      If IsNull(device_uuid) = False Then
       If Split(MountsLine, " ", "%%")[i] Like "*" & device_uuid & "*" Then
        mount_point = Split(MountsLine, " ", "%%")[1]
        filesystem_type = Split(MountsLine, " ", "%%")[2]
        mount_widtch = Split(MountsLine, " ", "%%")[3]
       Endif
      Endif

     Endif

     If IsNull(Finfosys.ComboBox3.Text) = True And Finfosys.ComboBox4.Text Like "*sr*" Then
      If Split(MountsLine, " ", "%%")[i] Like "*" & Finfosys.ComboBox4.Text & "*" Then
       mount_point = Split(MountsLine, " ", "%%")[1]
       filesystem_type = Split(MountsLine, " ", "%%")[2]
       mount_widtch = Split(MountsLine, " ", "%%")[3]
      Endif
     Endif
     
    Next
   Next
   Close #MOUNTS_PROC
   Endif
   
   If Access("/proc/swaps", gb.Read) = True Then
   SWAPS_PROC = Open "/proc/swaps"
    For Each SwapsLine In SWAPS_PROC.Lines
     For i = 0 To Split(SwapsLine, " ", "%%").Count - 1
      If IsNull(Finfosys.ComboBox3.Text) = False Then
       If Split(SwapsLine, " ", "%%")[i] Like "*" & Finfosys.ComboBox3.Text & "*" Then
        check_swap = Replace(Split(SwapsLine, " ", "%%")[0], "/dev/", "")
       Endif
      Endif
     Next
    Next
   Close #SWAPS_PROC
   Endif
  '
  '
  For i = 0 To Dir("/sys/block/", "sd*", gb.Directory).Count - 1
    With Stat("/sys/block/" & Dir("/sys/block/", "sd*")[i])
     For i2 = 0 To Split(.Link, "/").Count - 1
      If Split(.Link, "/")[i2] Like "*" & Finfosys.ComboBox4.Text & "*" Then
       
       If Split(.Link, "/")[4] Like "*ata*" Then
         Try hw_sata_spd_limit = Replace(File.Load("/sys/class/ata_link/" & Replace(Split(.Link, "/")[4], "ata", "link") & "/hw_sata_spd_limit"), "\n", "")
         Try sata_spd = Replace(File.Load("/sys/class/ata_link/" & Replace(Split(.Link, "/")[4], "ata", "link") & "/sata_spd"), "\n", "")
         Try sata_spd_limit = Replace(File.Load("/sys/class/ata_link/" & Replace(Split(.Link, "/")[4], "ata", "link") & "/sata_spd_limit"), "\n", "")
       Endif
       
       If Split(.Link, "/")[5] Like "*host*" Then
        CONNECTED_PORT = "Port:" & Space$(2) & Replace(Split(.Link, "/")[5], "host", "SATA")
       Else If Split(.Link, "/")[4] Like "*usb*" Then
        CONNECTED_PORT = "Port:" & Space$(2) & UCase(Split(.Link, "/")[4])
       Else
        CONNECTED_PORT = Null
       Endif
       
       If Split(.Link, "/")[4] Like "*usb*" Then
        Try USB_SPEED = Replace(File.Load("/sys/bus/usb/devices/" & Split(.Link, "/")[4] & "/" & Split(.Link, "/")[5] & "/speed"), "\n", "")
        Try USB_VERSION = Replace(File.Load("/sys/bus/usb/devices/" & Split(.Link, "/")[4] & "/" & Split(.Link, "/")[5] & "/version"), "\n", "")
        Try USB_BMAXPOWER = Replace(File.Load("/sys/bus/usb/devices/" & Split(.Link, "/")[4] & "/" & Split(.Link, "/")[5] & "/bMaxPower"), "\n", "")
       Endif
       
        ' For i3 = 0 To Dir("/sys/class/scsi_disk/").Count - 1
        '  If Split(Stat("/sys/class/scsi_disk/" & Dir("/sys/class/scsi_disk/")[i3]).Link, "/")[5] = Split(.Link, "/")[4] Then
        '   Print File.Load(Replace(Stat("/sys/class/scsi_disk/" & Dir("/sys/class/scsi_disk/")[i3]).Link, "../../", "/sys/") &/ "allow_restart")
        '   Print File.Load(Replace(Stat("/sys/class/scsi_disk/" & Dir("/sys/class/scsi_disk/")[i3]).Link, "../../", "/sys/") &/ "app_tag_own")
        '   Print File.Load(Replace(Stat("/sys/class/scsi_disk/" & Dir("/sys/class/scsi_disk/")[i3]).Link, "../../", "/sys/") &/ "cache_type")
        '   Print File.Load(Replace(Stat("/sys/class/scsi_disk/" & Dir("/sys/class/scsi_disk/")[i3]).Link, "../../", "/sys/") &/ "FUA")
        '   Print File.Load(Replace(Stat("/sys/class/scsi_disk/" & Dir("/sys/class/scsi_disk/")[i3]).Link, "../../", "/sys/") &/ "manage_start_stop")
        '   Print File.Load(Replace(Stat("/sys/class/scsi_disk/" & Dir("/sys/class/scsi_disk/")[i3]).Link, "../../", "/sys/") &/ "max_medium_access_timeouts")
        '   Print File.Load(Replace(Stat("/sys/class/scsi_disk/" & Dir("/sys/class/scsi_disk/")[i3]).Link, "../../", "/sys/") &/ "max_write_same_blocks")
        '   Print File.Load(Replace(Stat("/sys/class/scsi_disk/" & Dir("/sys/class/scsi_disk/")[i3]).Link, "../../", "/sys/") &/ "protection_mode")
        '   Print File.Load(Replace(Stat("/sys/class/scsi_disk/" & Dir("/sys/class/scsi_disk/")[i3]).Link, "../../", "/sys/") &/ "protection_type")
        '   Print File.Load(Replace(Stat("/sys/class/scsi_disk/" & Dir("/sys/class/scsi_disk/")[i3]).Link, "../../", "/sys/") &/ "provisioning_mode")
        '   Print File.Load(Replace(Stat("/sys/class/scsi_disk/" & Dir("/sys/class/scsi_disk/")[i3]).Link, "../../", "/sys/") &/ "thin_provisioning")
        '  Endif
        ' Next
       
      Endif
     Next
    End With
  Next
  
  Select Case USB_VERSION
    Case Like "*1.0*"
     USB_PIC = Picture.Load("Data/USB/usb1")
    Case Like "*1.1*"
     USB_PIC = Picture.Load("Data/USB/usb1")
    Case Like "*2.0*"
     USB_PIC = Picture.Load("Data/USB/usb2")
    Case Like "*2.1*"
     USB_PIC = Picture.Load("Data/USB/usb2")
    Case Like "*3*"
     USB_PIC = Picture.Load("Data/USB/usb3")
    Case Else
     USB_PIC = Null
  End Select

  
  Select Case sata_spd
    Case Like "*1.5*Gbps*"
     SATA_PIC = Picture.Load("Data/SATA/SATA1.jpg")
    Case Like "*3.0*Gbps*"
     SATA_PIC = Picture.Load("Data/SATA/SATA2.jpg")
    Case Like "*6.0*Gbps*"
     SATA_PIC = Picture.Load("Data/SATA/SATA3.jpg")
    Case Like "*<unknown>*"
     SATA_PIC = Picture.Load("Data/SATA/SATA.jpg")
    Case Else
     SATA_PIC = Null
  End Select
End

Function SETNULL()
USB_SPEED = Null
USB_VERSION = Null
USB_BMAXPOWER = Null

hw_sata_spd_limit = Null
sata_spd = Null
sata_spd_limit = Null

CONNECTED_PORT = Null
device_model = Null
device_vendor = Null
mount_point = Null
device_uuid = Null
real_size = Null
partition_size = Null
filesystem_type = Null
mount_widtch = Null
device_rev = Null
max_sectors = Null
device_state = Null
modalias = Null
check_swap = Null
removable = Null
ext_range = Null
range = Null
add_random = Null
discard_granularity = Null
discard_max_bytes = Null
discard_zeroes_data = Null
hw_sector_size = Null
max_hw_sectors_kb = Null
max_sectors_kb = Null
max_segments = Null
max_segment_size = Null
read_ahead_kb = Null
scheduler = Null
max_ratio = Null
min_ratio = Null
stable_pages_required = Null
logical_block_size = Null
iostats = Null 'iostats
minimum_io_size = Null
nomerges = Null
nr_requests = Null
optimal_io_size = Null
physical_block_size = Null
rotational = Null
rq_affinity = Null
End

Function SWAP_TOTAL() As Float
  Dim sTemp As String
  
  Exec ["cat", "/proc/meminfo"] To sTemp
   Try sTemp = Scan(sTemp, "*SwapTotal:*\n*")[1]
   If Error Then 
   sTemp = ""
  Else
   While Not IsDigit(Right(sTemp))
   sTemp = Left(sTemp, -1)
   Wend
   sTemp = Trim(sTemp)
  Endif
  
  If sTemp Then
    Try sTemp = Format(CInt(sTemp) / 1024, "0")
    If Not Error Then Return CFloat(sTemp)
  Endif
 
End

Function SWAP_FREE() As Float
  Dim sTemp As String
  
  Exec ["cat", "/proc/meminfo"] To sTemp
   Try sTemp = Scan(sTemp, "*SwapFree:*\n*")[1]
   If Error Then 
   sTemp = ""
  Else
   While Not IsDigit(Right(sTemp))
   sTemp = Left(sTemp, -1)
   Wend
   sTemp = Trim(sTemp)
  Endif
  
  If sTemp Then
    Try sTemp = Format(CInt(sTemp) / 1024, "0")
    If Not Error Then Return CFloat(sTemp)
  Endif
 
End

Function SWAP_USED() As Float
 Dim USED As Float
 Dim Frees As Float
 Dim Total As Float
 Total = CFloat(SWAP_TOTAL())
 Frees = CFloat(SWAP_FREE())
 USED = (Total - Frees)
 Return USED
End
