Class: VirtualBox::COM::FFIInterface

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

Constant Summary

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

- (FFIInterface) initialize

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

- (Object) session (readonly)

Returns the value of attribute session



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

def session
  @session
end

- (Object) virtualbox (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

- (Object) xpcom (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

+ (Object) create(lib_path = nil)

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

+ (Object) setup(lib_path = nil)

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

- (Object) initialize_com

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

- (Object) initialize_for_version(version)

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

- (Object) initialize_singletons

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