Class: VirtualBox::COM::FFIInterface

Inherits:
BaseInterface show all
Extended by:
FFI::Library
Includes:
Logger
Defined in:
lib/virtualbox/com/ffi_interface.rb

Constant Summary collapse

XPCOMC_VERSION =

Constant used to initialize the XPCOM C interface

0x00020000

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logger

included, #logger, #logger_output=

Methods inherited from BaseInterface

#on_lib_thread

Constructor Details

#initializeFFIInterface

Returns a new instance of FFIInterface.



43
44
45
46
# File 'lib/virtualbox/com/ffi_interface.rb', line 43

def initialize
  super
  initialize_com
end

Instance Attribute Details

#sessionObject (readonly)

Returns the value of attribute session.



18
19
20
# File 'lib/virtualbox/com/ffi_interface.rb', line 18

def session
  @session
end

#virtualboxObject (readonly)

The VirtualBox and Session interfaces, both of which are extremely important in interfacing with the VirtualBox API. Once these have been initialized, all other parts of the API can be accessed via these instances.



17
18
19
# File 'lib/virtualbox/com/ffi_interface.rb', line 17

def virtualbox
  @virtualbox
end

#xpcomObject (readonly)

VBOXXPCOMC struct. This typically won’t be used.



11
12
13
# File 'lib/virtualbox/com/ffi_interface.rb', line 11

def xpcom
  @xpcom
end

Class Method Details

.create(lib_path = nil) ⇒ Object

Sets up the FFI interface and also initializes the interface, returning an instance of VirtualBox::COM::FFIInterface.



23
24
25
26
# File 'lib/virtualbox/com/ffi_interface.rb', line 23

def create(lib_path=nil)
  setup(lib_path)
  new
end

.setup(lib_path = nil) ⇒ Object

Sets up the FFI interface by specifying the FFI library path and attaching the initial function (which can’t be done until the FFI library is specified).

Parameters:

  • lib_path (String) (defaults to: nil)


33
34
35
36
37
38
39
40
# File 'lib/virtualbox/com/ffi_interface.rb', line 33

def setup(lib_path=nil)
  # Setup the path to the C library
  lib_path ||= "/Applications/VirtualBox.app/Contents/MacOS/VBoxXPCOMC.dylib"

  # Attach to the interface
  ffi_lib lib_path
  attach_function :VBoxGetXPCOMCFunctions, [:uint], :pointer
end

Instance Method Details

#initialize_comObject

Initializes the COM interface with XPCOM. This sets up the ‘virtualbox`, `session`, and `xpcom` attributes. This should only be called once.



50
51
52
53
54
55
56
57
# File 'lib/virtualbox/com/ffi_interface.rb', line 50

def initialize_com
  # Get the pointer to the XPCOMC struct which contains the functions
  # to initialize
  xpcom_pointer = self.class.VBoxGetXPCOMCFunctions(XPCOMC_VERSION)
  @xpcom = FFI::VBOXXPCOMC.new(xpcom_pointer)

  initialize_singletons
end

#initialize_for_version(version) ⇒ Object

Initializes the FFI interface for a specific version.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/virtualbox/com/ffi_interface.rb', line 71

def initialize_for_version(version)
  logger.debug("FFI init: Trying version #{version}")

  # Setup the FFI classes
  VirtualBox::COM::FFI.setup(version)
  virtualbox_klass = COM::Util.versioned_interface(:VirtualBox)
  session_klass = COM::Util.versioned_interface(:Session)

  # Setup the OUT pointers
  virtualbox_ptr = ::FFI::MemoryPointer.new(:pointer)
  session_ptr = ::FFI::MemoryPointer.new(:pointer)

  # Call the initialization functions
  @xpcom[:pfnComInitialize].call(virtualbox_klass::IID_STR, virtualbox_ptr, session_klass::IID_STR, session_ptr)
  @virtualbox = virtualbox_klass.new(Implementer::FFI, self, virtualbox_ptr.get_pointer(0))
  @session = session_klass.new(Implementer::FFI, self, session_ptr.get_pointer(0))

  logger.debug("    -- Valid version")
  true
rescue Exception => e
  logger.debug("    -- Invalid version")
  false
end

#initialize_singletonsObject

Initializes the VirtualBox and Session interfaces. It goes through the various directories until it finds a working pair.



61
62
63
64
65
66
67
68
# File 'lib/virtualbox/com/ffi_interface.rb', line 61

def initialize_singletons
  interface_dir = File.expand_path(File.join(File.dirname(__FILE__), "interface"))
  Dir[File.join(interface_dir, "*")].each do |f|
    if File.directory?(f)
      return if initialize_for_version(File.basename(f))
    end
  end
end