Last active
December 20, 2015 23:39
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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