Skip to content

Instantly share code, notes, and snippets.

@alkalinecoffee
Last active December 20, 2015 23:39
Show Gist options
  • Save alkalinecoffee/6214399 to your computer and use it in GitHub Desktop.
Save alkalinecoffee/6214399 to your computer and use it in GitHub Desktop.
Using FFI to read from fibre channel HBA dll on a Windows box
require 'ffi'
class Fixnum
def hex(numchars=16)
self.to_s(numchars).upcase
end
end
module FFI
class Struct
class InlineArray
def to_wwn
wwnstruct = HBA::HBA_Wwn.new self.to_ptr
wwn = wwnstruct[:wwn][0].hex
1.upto(7) do |i|
hex = wwnstruct[:wwn][i].hex
if wwnstruct[:wwn][i] < 16
hex = "0#{hex}"
end
wwn = "#{wwn}:#{hex}"
end
wwn
end
end
end
end
module HBA
extend FFI::Library
typedef :uint32, :handle
class HBA_AdapterAttributes < FFI::Struct
layout :Manufacturer, [:char, 64],
:SerialNumber, [:char, 64],
:Model, [:char, 256],
:ModelDescription, [:char, 256],
:NodeWWN, [:uint8, 8], # this probably needs to be another struct
:NodeSymbolicName, [:char, 256],
:HardwareVersion, [:char, 256],
:DriverVersion, [:char, 256],
:OptionROMVersion, [:char, 256],
:FirmwareVersion, [:char, 256],
:VendorSpecificID, :uint32,
:NumberOfPorts, :int,
:DriverName, [:char, 256]
end
class HBA_Wwn < FFI::Struct
layout :wwn, [:uint8, 8]
end
pwdir = Dir.getwd.gsub('/', '\\')
ffi_lib 'C:\Program Files\QLogic Corporation\SANsurfer\ql2xhai2.dll'
ffi_convention :stdcall
# if we get a segmentation fault, the wrong data type was probably used
attach_function :HBA_GetVersion, [], :uint32
attach_function :HBA_GetNumberOfAdapters, [], :uint32
attach_function :HBA_LoadLibrary, [], :uint32
attach_function :HBA_GetAdapterName, [:uint32, :pointer], :uint32
attach_function :HBA_OpenAdapter, [:pointer], :handle
attach_function :HBA_CloseAdapter, [:uint32], :void
attach_function :HBA_GetAdapterAttributes, [:handle, :pointer], :uint32
end
HBA.HBA_LoadLibrary
adapter_count = HBA.HBA_GetNumberOfAdapters
hba_version = HBA.HBA_GetVersion
puts "Version: #{hba_version}"
puts "Count: #{adapter_count}"
puts "-----------"
x = adapter_count - 1
(0..x).each do |i|
adapter = FFI::MemoryPointer.new :char, 256
HBA.HBA_GetAdapterName(i, adapter)
handle = HBA.HBA_OpenAdapter(adapter.get_string(0))
puts "Handle opened: #{handle}"
puts "Adapter name: #{adapter.get_string(0)}"
attribs = HBA::HBA_AdapterAttributes.new
HBA::HBA_GetAdapterAttributes(i, attribs)
puts "Manufacturer: #{attribs[:Manufacturer]}"
puts "Serial: #{attribs[:SerialNumber]}"
puts "Model: #{attribs[:Model]}"
puts "Description: #{attribs[:ModelDescription]}"
puts "NodeWWN: #{attribs[:NodeWWN].to_wwn}"
puts "SymbolicName: #{attribs[:NodeSymbolicName]}"
puts "HardwareVersion: #{attribs[:HardwareVersion]}"
puts "DriverVersion: #{attribs[:DriverVersion]}"
puts "OptionROMVersion: #{attribs[:OptionROMVersion]}"
puts "FirmwareVersion: #{attribs[:FirmwareVersion]}"
puts "VendorSpecificID: #{attribs[:VendorSpecificID]}"
puts "NumberOfPorts: #{attribs[:NumberOfPorts]}"
puts "DriverName: #{attribs[:DriverName]}"
HBA.HBA_CloseAdapter(handle)
puts "Handle closed"
puts "-----------"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment