bbrowning-virtualbox 0.7.6.dev
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/.yardopts +3 -0
- data/Gemfile +16 -0
- data/LICENSE +19 -0
- data/Rakefile +33 -0
- data/Readme.md +70 -0
- data/docs/GettingStarted.md +196 -0
- data/docs/WhatsNew.md +12 -0
- data/features/README.md +33 -0
- data/features/global.feature +19 -0
- data/features/global_extra_data.feature +27 -0
- data/features/step_definitions/abstract_model_steps.rb +39 -0
- data/features/step_definitions/extra_data_steps.rb +36 -0
- data/features/step_definitions/global_steps.rb +29 -0
- data/features/step_definitions/nat_engine_steps.rb +76 -0
- data/features/step_definitions/network_adapter_steps.rb +38 -0
- data/features/step_definitions/shared_folder_steps.rb +76 -0
- data/features/step_definitions/snapshot_steps.rb +74 -0
- data/features/step_definitions/storage_controller_steps.rb +16 -0
- data/features/step_definitions/virtualbox_steps.rb +17 -0
- data/features/step_definitions/vm_steps.rb +50 -0
- data/features/support/env.rb +61 -0
- data/features/support/helpers.rb +38 -0
- data/features/support/hooks.rb +30 -0
- data/features/support/ordered_hash.rb +49 -0
- data/features/support/vboxmanage.rb +191 -0
- data/features/version.feature +16 -0
- data/features/vm.feature +13 -0
- data/features/vm_bios.feature +29 -0
- data/features/vm_cpu.feature +29 -0
- data/features/vm_extra_data.feature +35 -0
- data/features/vm_hw_virt.feature +29 -0
- data/features/vm_nat_engine.feature +57 -0
- data/features/vm_network_adapters.feature +27 -0
- data/features/vm_shared_folders.feature +42 -0
- data/features/vm_snapshots.feature +29 -0
- data/features/vm_storage_controllers.feature +11 -0
- data/lib/virtualbox.rb +11 -0
- data/lib/virtualbox/abstract_model.rb +281 -0
- data/lib/virtualbox/abstract_model/attributable.rb +290 -0
- data/lib/virtualbox/abstract_model/dirty.rb +177 -0
- data/lib/virtualbox/abstract_model/interface_attributes.rb +98 -0
- data/lib/virtualbox/abstract_model/relatable.rb +332 -0
- data/lib/virtualbox/abstract_model/validatable.rb +167 -0
- data/lib/virtualbox/abstract_model/version_matcher.rb +35 -0
- data/lib/virtualbox/appliance.rb +62 -0
- data/lib/virtualbox/audio_adapter.rb +52 -0
- data/lib/virtualbox/bios.rb +50 -0
- data/lib/virtualbox/com.rb +23 -0
- data/lib/virtualbox/com/abstract_enum.rb +43 -0
- data/lib/virtualbox/com/abstract_implementer.rb +45 -0
- data/lib/virtualbox/com/abstract_interface.rb +167 -0
- data/lib/virtualbox/com/base_interface.rb +38 -0
- data/lib/virtualbox/com/ffi/interface.rb +150 -0
- data/lib/virtualbox/com/ffi/interfaces.rb +54 -0
- data/lib/virtualbox/com/ffi/util.rb +119 -0
- data/lib/virtualbox/com/ffi/vboxxpcomc.rb +31 -0
- data/lib/virtualbox/com/ffi_interface.rb +96 -0
- data/lib/virtualbox/com/implementer/base.rb +59 -0
- data/lib/virtualbox/com/implementer/ffi.rb +361 -0
- data/lib/virtualbox/com/implementer/mscom.rb +175 -0
- data/lib/virtualbox/com/implementer/nil.rb +10 -0
- data/lib/virtualbox/com/interface/3.1.x/access_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/appliance.rb +22 -0
- data/lib/virtualbox/com/interface/3.1.x/audio_adapter.rb +15 -0
- data/lib/virtualbox/com/interface/3.1.x/audio_controller_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/audio_driver_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/bios_boot_menu_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/bios_settings.rb +21 -0
- data/lib/virtualbox/com/interface/3.1.x/clipboard_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/console.rb +50 -0
- data/lib/virtualbox/com/interface/3.1.x/cpu_property_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/device_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/dhcp_server.rb +22 -0
- data/lib/virtualbox/com/interface/3.1.x/firmware_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/guest_os_type.rb +23 -0
- data/lib/virtualbox/com/interface/3.1.x/host.rb +42 -0
- data/lib/virtualbox/com/interface/3.1.x/host_network_interface.rb +30 -0
- data/lib/virtualbox/com/interface/3.1.x/host_network_interface_medium_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/host_network_interface_status.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/host_network_interface_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/host_usb_device.rb +13 -0
- data/lib/virtualbox/com/interface/3.1.x/host_usb_device_filter.rb +13 -0
- data/lib/virtualbox/com/interface/3.1.x/hw_virt_ex_property_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/machine.rb +105 -0
- data/lib/virtualbox/com/interface/3.1.x/machine_state.rb +14 -0
- data/lib/virtualbox/com/interface/3.1.x/medium.rb +50 -0
- data/lib/virtualbox/com/interface/3.1.x/medium_attachment.rb +18 -0
- data/lib/virtualbox/com/interface/3.1.x/medium_format.rb +18 -0
- data/lib/virtualbox/com/interface/3.1.x/medium_state.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/medium_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/medium_variant.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/network_adapter.rb +30 -0
- data/lib/virtualbox/com/interface/3.1.x/network_adapter_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/network_attachment_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/nsiexception.rb +23 -0
- data/lib/virtualbox/com/interface/3.1.x/nsisupports.rb +15 -0
- data/lib/virtualbox/com/interface/3.1.x/parallel_port.rb +17 -0
- data/lib/virtualbox/com/interface/3.1.x/port_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/progress.rb +63 -0
- data/lib/virtualbox/com/interface/3.1.x/serial_port.rb +19 -0
- data/lib/virtualbox/com/interface/3.1.x/session.rb +18 -0
- data/lib/virtualbox/com/interface/3.1.x/session_state.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/session_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/shared_folder.rb +17 -0
- data/lib/virtualbox/com/interface/3.1.x/snapshot.rb +20 -0
- data/lib/virtualbox/com/interface/3.1.x/storage_bus.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/storage_controller.rb +23 -0
- data/lib/virtualbox/com/interface/3.1.x/storage_controller_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/system_properties.rb +37 -0
- data/lib/virtualbox/com/interface/3.1.x/usb_controller.rb +20 -0
- data/lib/virtualbox/com/interface/3.1.x/usb_device.rb +24 -0
- data/lib/virtualbox/com/interface/3.1.x/usb_device_filter.rb +23 -0
- data/lib/virtualbox/com/interface/3.1.x/usb_device_filter_action.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/usb_device_state.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/virtual_box_error_info.rb +17 -0
- data/lib/virtualbox/com/interface/3.1.x/virtual_system_description.rb +19 -0
- data/lib/virtualbox/com/interface/3.1.x/virtual_system_description_type.rb +14 -0
- data/lib/virtualbox/com/interface/3.1.x/virtual_system_description_value_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/virtualbox.rb +67 -0
- data/lib/virtualbox/com/interface/3.1.x/vrdp_auth_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/vrdp_server.rb +19 -0
- data/lib/virtualbox/com/interface/3.2.x/access_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/appliance.rb +22 -0
- data/lib/virtualbox/com/interface/3.2.x/audio_adapter.rb +15 -0
- data/lib/virtualbox/com/interface/3.2.x/audio_controller_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/audio_driver_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/bios_boot_menu_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/bios_settings.rb +21 -0
- data/lib/virtualbox/com/interface/3.2.x/clipboard_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/console.rb +50 -0
- data/lib/virtualbox/com/interface/3.2.x/cpu_property_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/device_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/dhcp_server.rb +22 -0
- data/lib/virtualbox/com/interface/3.2.x/firmware_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/guest.rb +13 -0
- data/lib/virtualbox/com/interface/3.2.x/guest_os_type.rb +33 -0
- data/lib/virtualbox/com/interface/3.2.x/host.rb +43 -0
- data/lib/virtualbox/com/interface/3.2.x/host_network_interface.rb +30 -0
- data/lib/virtualbox/com/interface/3.2.x/host_network_interface_medium_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/host_network_interface_status.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/host_network_interface_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/host_usb_device.rb +13 -0
- data/lib/virtualbox/com/interface/3.2.x/host_usb_device_filter.rb +13 -0
- data/lib/virtualbox/com/interface/3.2.x/hw_virt_ex_property_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/keyboard_hid_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/machine.rb +118 -0
- data/lib/virtualbox/com/interface/3.2.x/machine_state.rb +14 -0
- data/lib/virtualbox/com/interface/3.2.x/medium.rb +51 -0
- data/lib/virtualbox/com/interface/3.2.x/medium_attachment.rb +18 -0
- data/lib/virtualbox/com/interface/3.2.x/medium_format.rb +18 -0
- data/lib/virtualbox/com/interface/3.2.x/medium_state.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/medium_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/medium_variant.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/nat_alias_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/nat_engine.rb +27 -0
- data/lib/virtualbox/com/interface/3.2.x/nat_protocol.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/network_adapter.rb +34 -0
- data/lib/virtualbox/com/interface/3.2.x/network_adapter_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/network_attachment_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/nsiexception.rb +23 -0
- data/lib/virtualbox/com/interface/3.2.x/nsisupports.rb +15 -0
- data/lib/virtualbox/com/interface/3.2.x/parallel_port.rb +17 -0
- data/lib/virtualbox/com/interface/3.2.x/pointing_hid_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/port_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/progress.rb +63 -0
- data/lib/virtualbox/com/interface/3.2.x/serial_port.rb +19 -0
- data/lib/virtualbox/com/interface/3.2.x/session.rb +18 -0
- data/lib/virtualbox/com/interface/3.2.x/session_state.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/session_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/shared_folder.rb +17 -0
- data/lib/virtualbox/com/interface/3.2.x/snapshot.rb +20 -0
- data/lib/virtualbox/com/interface/3.2.x/storage_bus.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/storage_controller.rb +24 -0
- data/lib/virtualbox/com/interface/3.2.x/storage_controller_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/system_properties.rb +42 -0
- data/lib/virtualbox/com/interface/3.2.x/usb_controller.rb +21 -0
- data/lib/virtualbox/com/interface/3.2.x/usb_device.rb +24 -0
- data/lib/virtualbox/com/interface/3.2.x/usb_device_filter.rb +23 -0
- data/lib/virtualbox/com/interface/3.2.x/usb_device_filter_action.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/usb_device_state.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/virtual_box_error_info.rb +17 -0
- data/lib/virtualbox/com/interface/3.2.x/virtual_system_description.rb +19 -0
- data/lib/virtualbox/com/interface/3.2.x/virtual_system_description_type.rb +14 -0
- data/lib/virtualbox/com/interface/3.2.x/virtual_system_description_value_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/virtualbox.rb +67 -0
- data/lib/virtualbox/com/interface/3.2.x/vrdp_auth_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/vrdp_server.rb +21 -0
- data/lib/virtualbox/com/mscom_interface.rb +44 -0
- data/lib/virtualbox/com/nil_interface.rb +7 -0
- data/lib/virtualbox/com/util.rb +32 -0
- data/lib/virtualbox/cpu.rb +61 -0
- data/lib/virtualbox/dhcp_server.rb +89 -0
- data/lib/virtualbox/dvd.rb +27 -0
- data/lib/virtualbox/exceptions.rb +39 -0
- data/lib/virtualbox/ext/byte_normalizer.rb +17 -0
- data/lib/virtualbox/ext/glob_loader.rb +22 -0
- data/lib/virtualbox/ext/logger.rb +38 -0
- data/lib/virtualbox/ext/platform.rb +27 -0
- data/lib/virtualbox/ext/subclass_listing.rb +24 -0
- data/lib/virtualbox/extra_data.rb +127 -0
- data/lib/virtualbox/forwarded_port.rb +222 -0
- data/lib/virtualbox/global.rb +102 -0
- data/lib/virtualbox/guest_property.rb +116 -0
- data/lib/virtualbox/hard_drive.rb +246 -0
- data/lib/virtualbox/host.rb +71 -0
- data/lib/virtualbox/host_network_interface.rb +137 -0
- data/lib/virtualbox/hw_virtualization.rb +63 -0
- data/lib/virtualbox/lib.rb +84 -0
- data/lib/virtualbox/media.rb +20 -0
- data/lib/virtualbox/medium.rb +145 -0
- data/lib/virtualbox/medium_attachment.rb +61 -0
- data/lib/virtualbox/nat_engine.rb +71 -0
- data/lib/virtualbox/nat_forwarded_port.rb +171 -0
- data/lib/virtualbox/network_adapter.rb +166 -0
- data/lib/virtualbox/proxies/collection.rb +57 -0
- data/lib/virtualbox/shared_folder.rb +220 -0
- data/lib/virtualbox/snapshot.rb +185 -0
- data/lib/virtualbox/storage_controller.rb +160 -0
- data/lib/virtualbox/system_properties.rb +74 -0
- data/lib/virtualbox/usb_controller.rb +59 -0
- data/lib/virtualbox/usb_device_filter.rb +74 -0
- data/lib/virtualbox/version.rb +36 -0
- data/lib/virtualbox/virtual_system_description.rb +47 -0
- data/lib/virtualbox/vm.rb +684 -0
- data/lib/virtualbox/vrdp_server.rb +59 -0
- data/test/test_helper.rb +18 -0
- data/test/virtualbox/abstract_model/attributable_test.rb +269 -0
- data/test/virtualbox/abstract_model/dirty_test.rb +83 -0
- data/test/virtualbox/abstract_model/interface_attributes_test.rb +194 -0
- data/test/virtualbox/abstract_model/relatable_test.rb +348 -0
- data/test/virtualbox/abstract_model/validatable_test.rb +308 -0
- data/test/virtualbox/abstract_model/version_matcher_test.rb +41 -0
- data/test/virtualbox/abstract_model_test.rb +462 -0
- data/test/virtualbox/appliance_test.rb +159 -0
- data/test/virtualbox/audio_adapter_test.rb +83 -0
- data/test/virtualbox/bios_test.rb +83 -0
- data/test/virtualbox/com/abstract_enum_test.rb +49 -0
- data/test/virtualbox/com/abstract_implementer_test.rb +40 -0
- data/test/virtualbox/com/abstract_interface_test.rb +140 -0
- data/test/virtualbox/com/ffi/interface_test.rb +249 -0
- data/test/virtualbox/com/ffi/util_test.rb +108 -0
- data/test/virtualbox/com/ffi_interface_test.rb +42 -0
- data/test/virtualbox/com/implementer/base_test.rb +38 -0
- data/test/virtualbox/com/implementer/ffi_test.rb +527 -0
- data/test/virtualbox/com/implementer/mscom_test.rb +247 -0
- data/test/virtualbox/com/mscom_interface_test.rb +17 -0
- data/test/virtualbox/com/util_test.rb +17 -0
- data/test/virtualbox/cpu_test.rb +103 -0
- data/test/virtualbox/dhcp_server_test.rb +165 -0
- data/test/virtualbox/dvd_test.rb +28 -0
- data/test/virtualbox/ext/byte_normalizer_test.rb +34 -0
- data/test/virtualbox/ext/platform_test.rb +50 -0
- data/test/virtualbox/ext/subclass_listing_test.rb +25 -0
- data/test/virtualbox/extra_data_test.rb +155 -0
- data/test/virtualbox/forwarded_port_test.rb +286 -0
- data/test/virtualbox/global_test.rb +46 -0
- data/test/virtualbox/hard_drive_test.rb +141 -0
- data/test/virtualbox/host_network_interface_test.rb +254 -0
- data/test/virtualbox/host_test.rb +94 -0
- data/test/virtualbox/hw_virtualization_test.rb +103 -0
- data/test/virtualbox/lib_test.rb +93 -0
- data/test/virtualbox/medium_attachment_test.rb +147 -0
- data/test/virtualbox/medium_test.rb +192 -0
- data/test/virtualbox/nat_engine_test.rb +106 -0
- data/test/virtualbox/nat_forwarded_port_test.rb +222 -0
- data/test/virtualbox/network_adapter_test.rb +191 -0
- data/test/virtualbox/proxies/collection_test.rb +102 -0
- data/test/virtualbox/shared_folder_test.rb +219 -0
- data/test/virtualbox/snapshot_test.rb +231 -0
- data/test/virtualbox/storage_controller_test.rb +197 -0
- data/test/virtualbox/system_properties_test.rb +87 -0
- data/test/virtualbox/usb_controller_test.rb +112 -0
- data/test/virtualbox/usb_device_filter_test.rb +93 -0
- data/test/virtualbox/version_test.rb +59 -0
- data/test/virtualbox/virtual_system_description_test.rb +61 -0
- data/test/virtualbox/vm_test.rb +637 -0
- data/test/virtualbox/vrdp_server_test.rb +83 -0
- data/test/virtualbox_test.rb +11 -0
- data/virtualbox.gemspec +25 -0
- metadata +397 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module VirtualBox
|
4
|
+
module COM
|
5
|
+
class BaseInterface
|
6
|
+
def initialize
|
7
|
+
@task_queue = Queue.new
|
8
|
+
|
9
|
+
@lib_thread = Thread.new(@task_queue) do |queue|
|
10
|
+
while true
|
11
|
+
task, result = queue.pop
|
12
|
+
|
13
|
+
# Run the task, set the return value, and run the waiter
|
14
|
+
# which will simply finish that thread
|
15
|
+
result << task.call
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# This function takes a block and runs it on a thread which is
|
21
|
+
# guaranteed to be the same since the first time this is
|
22
|
+
# called. This is required by the MSCOM implementation and is a
|
23
|
+
# good idea in general so that multiple API calls aren't firing
|
24
|
+
# at once.
|
25
|
+
def on_lib_thread(&task)
|
26
|
+
# If we're already on the lib thread, then just run it!
|
27
|
+
return task.call if Thread.current == @lib_thread
|
28
|
+
|
29
|
+
# Add the task to the queue
|
30
|
+
result = Queue.new
|
31
|
+
@task_queue << [task, result]
|
32
|
+
|
33
|
+
# Pop the result off of the result queue
|
34
|
+
result.pop
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module VirtualBox
|
4
|
+
module COM
|
5
|
+
module FFI
|
6
|
+
extend ::FFI::Library
|
7
|
+
|
8
|
+
# FFI specific types
|
9
|
+
NSRESULT_TYPE = :uint
|
10
|
+
|
11
|
+
# Creates all the FFI classes for a given version.
|
12
|
+
def self.for_version(version, &block)
|
13
|
+
@__module = Module.new
|
14
|
+
::VirtualBox::COM::Util.set_interface_version(version)
|
15
|
+
const_set(::VirtualBox::COM::Util.version_const, @__module)
|
16
|
+
instance_eval(&block)
|
17
|
+
@__module = Kernel
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns a Class which creates an FFI interface to the specified
|
21
|
+
# com interface and potentially a parent class as well.
|
22
|
+
def self.create_interface(interface, parent=nil)
|
23
|
+
klass = Class.new(Interface)
|
24
|
+
@__module.const_set(interface, klass)
|
25
|
+
klass.com_interface(interface, parent)
|
26
|
+
klass
|
27
|
+
end
|
28
|
+
|
29
|
+
# Represents a VirtualBox XPCOM C interface, which is a C struct
|
30
|
+
# which emulates an object (a struct with function pointers
|
31
|
+
# and getters/setters). This class does **a lot** of magic which pretty
|
32
|
+
# much represents everything wrong about ruby programmers, but keep
|
33
|
+
# in mind it is well tested and well commented, and the meta-programming
|
34
|
+
# was done out of a need to keep things DRY between Windows and Unix
|
35
|
+
# operating systems.
|
36
|
+
class Interface
|
37
|
+
extend ::FFI::Library
|
38
|
+
|
39
|
+
attr_reader :vtbl_parent
|
40
|
+
attr_reader :vtbl
|
41
|
+
|
42
|
+
class << self
|
43
|
+
# Sets up the args to the FFI::Struct `layout` method. This
|
44
|
+
# method defines all the callbacks necessary for working with
|
45
|
+
# FFI and also sets up any layout args to send in. The way the
|
46
|
+
# XPCOM C structs are setup, the properties are first, in
|
47
|
+
# `GetFoo` and `SetFoo` format. And the functions are next. They are
|
48
|
+
# put into the struct in the order defined in the {AbstractInterface}.
|
49
|
+
def com_interface(interface, parent=nil)
|
50
|
+
# Create the parent class and vtbl class
|
51
|
+
interface = ::VirtualBox::COM::Util.versioned_interface(interface)
|
52
|
+
define_vtbl_parent_for_interface(interface)
|
53
|
+
define_vtbl_for_interface(interface, parent)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Creates the parent of the vtbl class associated with a given
|
57
|
+
# interface.
|
58
|
+
def define_vtbl_parent_for_interface(interface)
|
59
|
+
@vtbl_parent_klass = Class.new(::FFI::Struct)
|
60
|
+
@vtbl_parent_klass.layout(:vtbl, :pointer)
|
61
|
+
|
62
|
+
# Set the constant
|
63
|
+
const_set("VtblParent", @vtbl_parent_klass)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Creates the vtbl class associated with a given interface.
|
67
|
+
def define_vtbl_for_interface(interface, parent=nil)
|
68
|
+
# Define the properties, then the functions, since thats the order
|
69
|
+
# the FFI structs are in
|
70
|
+
layout_args.clear
|
71
|
+
define_interface_parent(parent)
|
72
|
+
define_interface_properties(interface)
|
73
|
+
define_interface_functions(interface)
|
74
|
+
|
75
|
+
# Finally create the classes (the struct and the structs vtbl)
|
76
|
+
@vtbl_klass = Class.new(::FFI::Struct)
|
77
|
+
|
78
|
+
# Set the constant within this class
|
79
|
+
const_set("Vtbl", @vtbl_klass).layout(*layout_args.flatten)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Defines the parent item of the layout. Since the VirtualBox XPCOM C
|
83
|
+
# library emulates an object-oriented environment using structs, the parent
|
84
|
+
# instance is pointed to by the first member of the struct. This method
|
85
|
+
# sets up that member.
|
86
|
+
#
|
87
|
+
# @param [Symbol] parent The name of the parent represented by a symbol
|
88
|
+
def define_interface_parent(parent)
|
89
|
+
return if parent.nil?
|
90
|
+
|
91
|
+
parent_klass = Object.module_eval("::VirtualBox::COM::FFI::#{::VirtualBox::COM::Util.version_const}::#{parent}::Vtbl")
|
92
|
+
layout_args << [:superklass, parent_klass]
|
93
|
+
end
|
94
|
+
|
95
|
+
# Defines all the properties on a com interface.
|
96
|
+
def define_interface_properties(interface)
|
97
|
+
interface.properties.each do |name, opts|
|
98
|
+
# Define the getter
|
99
|
+
define_interface_function("get_#{name}".to_sym, opts[:value_type])
|
100
|
+
|
101
|
+
# Define the setter unless the property is readonly
|
102
|
+
define_interface_function("set_#{name}".to_sym, nil, [opts[:value_type]]) unless opts[:opts] && opts[:opts][:readonly]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Defines all the functions on a com interface.
|
107
|
+
def define_interface_functions(interface)
|
108
|
+
interface.functions.each do |name, opts|
|
109
|
+
# Define the function
|
110
|
+
define_interface_function(name, opts[:value_type], opts[:spec].dup)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Defines a single function of a com interface
|
115
|
+
def define_interface_function(name, return_type, spec=[])
|
116
|
+
# Append the return type to the spec as an out parameter (this is how
|
117
|
+
# the C API handles it)
|
118
|
+
spec << [:out, return_type] unless return_type.nil?
|
119
|
+
|
120
|
+
# Define the "callback" type for the FFI module
|
121
|
+
callback(name, Util.spec_to_ffi(spec), NSRESULT_TYPE)
|
122
|
+
|
123
|
+
# Add to the layout args
|
124
|
+
layout_args << [name, name]
|
125
|
+
end
|
126
|
+
|
127
|
+
# Returns an array of the layout args to send to `layout` eventually.
|
128
|
+
#
|
129
|
+
# @return [Array]
|
130
|
+
def layout_args
|
131
|
+
@_layout_args ||= []
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Initializes the interface to the FFI struct with the given pointer. The
|
136
|
+
# pointer is used to initialize the VtblParent which is used to initialize
|
137
|
+
# the Vtbl itself.
|
138
|
+
def initialize(pointer)
|
139
|
+
initialize_vtbl(pointer)
|
140
|
+
end
|
141
|
+
|
142
|
+
def initialize_vtbl(pointer)
|
143
|
+
klass = self.class
|
144
|
+
@vtbl_parent = klass::VtblParent.new(pointer)
|
145
|
+
@vtbl = klass::Vtbl.new(vtbl_parent[:vtbl])
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module VirtualBox
|
2
|
+
module COM
|
3
|
+
module FFI
|
4
|
+
# Creates all the interfaces for the FFI implementation. Eventually this
|
5
|
+
# file should be conditionally loaded based on OS, so that Windows users
|
6
|
+
# don't have to wait for all this translation to occur.
|
7
|
+
def self.setup(version)
|
8
|
+
# TODO: This is so hacky and hard to maintain. Can we
|
9
|
+
# programatically get the modules in a namespace and
|
10
|
+
# instantiate them somehow?
|
11
|
+
for_version version do
|
12
|
+
create_interface(:NSISupports)
|
13
|
+
create_interface(:NSIException, :NSISupports)
|
14
|
+
create_interface(:Session, :NSISupports)
|
15
|
+
create_interface(:VirtualBox, :NSISupports)
|
16
|
+
create_interface(:Appliance, :NSISupports)
|
17
|
+
create_interface(:AudioAdapter, :NSISupports)
|
18
|
+
create_interface(:BIOSSettings, :NSISupports)
|
19
|
+
create_interface(:Console, :NSISupports)
|
20
|
+
create_interface(:DHCPServer, :NSISupports)
|
21
|
+
create_interface(:GuestOSType, :NSISupports)
|
22
|
+
create_interface(:Host, :NSISupports)
|
23
|
+
create_interface(:HostNetworkInterface, :NSISupports)
|
24
|
+
create_interface(:Machine, :NSISupports)
|
25
|
+
create_interface(:Medium, :NSISupports)
|
26
|
+
create_interface(:MediumAttachment, :NSISupports)
|
27
|
+
create_interface(:MediumFormat, :NSISupports)
|
28
|
+
create_interface(:NetworkAdapter, :NSISupports)
|
29
|
+
create_interface(:ParallelPort, :NSISupports)
|
30
|
+
create_interface(:Progress, :NSISupports)
|
31
|
+
create_interface(:SerialPort, :NSISupports)
|
32
|
+
create_interface(:SharedFolder, :NSISupports)
|
33
|
+
create_interface(:Snapshot, :NSISupports)
|
34
|
+
create_interface(:StorageController, :NSISupports)
|
35
|
+
create_interface(:SystemProperties, :NSISupports)
|
36
|
+
create_interface(:USBController, :NSISupports)
|
37
|
+
create_interface(:USBDevice, :NSISupports)
|
38
|
+
create_interface(:USBDeviceFilter, :NSISupports)
|
39
|
+
create_interface(:VirtualBoxErrorInfo, :NSIException)
|
40
|
+
create_interface(:VirtualSystemDescription, :NSISupports)
|
41
|
+
create_interface(:VRDPServer, :NSISupports)
|
42
|
+
|
43
|
+
create_interface(:HostUSBDevice, :USBDevice)
|
44
|
+
create_interface(:HostUSBDeviceFilter, :USBDeviceFilter)
|
45
|
+
|
46
|
+
# 3.2.x interfaces
|
47
|
+
if version == "3.2.x"
|
48
|
+
create_interface(:NATEngine, :NSISupports)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module VirtualBox
|
2
|
+
module COM
|
3
|
+
module FFI
|
4
|
+
# Class which contains many class-level utility methods to assist
|
5
|
+
# with the FFI interface. These functions range from converting a
|
6
|
+
# function spec to a FFI parameter list to dereferencing pointers.
|
7
|
+
class Util
|
8
|
+
class << self
|
9
|
+
# Finds and returns the `COM::Interface` class associated with the type.
|
10
|
+
# If the class does not exist, a `NameError` will be raised.
|
11
|
+
#
|
12
|
+
# @return [Class]
|
13
|
+
def interface_klass(type)
|
14
|
+
::VirtualBox::COM::Util.versioned_interface(type)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Finds the versioned interface for the FFI module.
|
18
|
+
#
|
19
|
+
# @return [Class]
|
20
|
+
def versioned_interface(interface)
|
21
|
+
::VirtualBox::COM::FFI.const_get(::VirtualBox::COM::Util.version_const).const_get(interface)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Converts a function spec from {AbstractInterface} to an FFI
|
25
|
+
# function spec. This handles custom types (unicode strings,
|
26
|
+
# arrays, and out-parameters) and will return a perfectly valid
|
27
|
+
# array ready to be passed into `callback`.
|
28
|
+
#
|
29
|
+
# @param [Array] spec The function spec
|
30
|
+
# @return [Array]
|
31
|
+
def spec_to_ffi(spec)
|
32
|
+
spec = spec.collect do |item|
|
33
|
+
if item.is_a?(Array) && item[0] == :out
|
34
|
+
if item[1].is_a?(Array)
|
35
|
+
# The out is an array of items, so we add in two pointers:
|
36
|
+
# one for size and one for the array
|
37
|
+
[:pointer, :pointer]
|
38
|
+
else
|
39
|
+
# A regular out parameter is just a single pointer
|
40
|
+
:pointer
|
41
|
+
end
|
42
|
+
elsif item.is_a?(Array) && item.length == 1
|
43
|
+
# The parameter is an array of somethings
|
44
|
+
[T_UINT32, :pointer]
|
45
|
+
elsif item == WSTRING
|
46
|
+
# Unicode strings are simply pointers
|
47
|
+
:pointer
|
48
|
+
elsif item.to_s[0,1] == item.to_s[0,1].upcase
|
49
|
+
begin
|
50
|
+
# Try to get the class from the interfaces
|
51
|
+
interface = interface_klass(item.to_sym)
|
52
|
+
|
53
|
+
if interface.superclass == COM::AbstractInterface
|
54
|
+
:pointer
|
55
|
+
elsif interface.superclass == COM::AbstractEnum
|
56
|
+
T_UINT32
|
57
|
+
end
|
58
|
+
rescue NameError
|
59
|
+
# Default to a pointer, since not all interfaces are implemented
|
60
|
+
:pointer
|
61
|
+
end
|
62
|
+
else
|
63
|
+
# Unknown items are simply passed as-is, hopefully FFI
|
64
|
+
# will catch any problems
|
65
|
+
item
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Prepend a :pointer to represent the `this` parameter required
|
70
|
+
# for the FFI parameter lists
|
71
|
+
spec.unshift(:pointer).flatten
|
72
|
+
end
|
73
|
+
|
74
|
+
# An "almost complete" camel-caser. Camel cases a string with a few
|
75
|
+
# exceptions. For example: `get_foo` becomes `GetFoo`, but `get_os_type`
|
76
|
+
# becomes `GetOSType` since `os` is a special case.
|
77
|
+
#
|
78
|
+
# @param [String] string The string to camel case
|
79
|
+
# @return [String]
|
80
|
+
def camelize(string)
|
81
|
+
special_cases = {
|
82
|
+
"os" => "OS",
|
83
|
+
"dhcp" => "DHCP",
|
84
|
+
"dvd" => "DVD",
|
85
|
+
"usb" => "USB",
|
86
|
+
"vram" => "VRAM",
|
87
|
+
"3d" => "3D",
|
88
|
+
"bios" => "BIOS",
|
89
|
+
"vrdp" => "VRDP",
|
90
|
+
"hw" => "HW",
|
91
|
+
"png" => "PNG",
|
92
|
+
"io" => "IO",
|
93
|
+
"apic" => "APIC",
|
94
|
+
"acpi" => "ACPI",
|
95
|
+
"pxe" => "PXE",
|
96
|
+
"nat" => "NAT",
|
97
|
+
"ide" => "IDE",
|
98
|
+
"vfs" => "VFS",
|
99
|
+
"ip" => "IP",
|
100
|
+
"vdi" => "VDI",
|
101
|
+
"cpu" => "CPU",
|
102
|
+
"ram" => "RAM",
|
103
|
+
"hdd" => "HDD",
|
104
|
+
"rtc" => "RTC",
|
105
|
+
"utc" => "UTC",
|
106
|
+
"io" => "IO"
|
107
|
+
}
|
108
|
+
|
109
|
+
parts = string.to_s.split(/_/).collect do |part|
|
110
|
+
special_cases[part] || part.capitalize
|
111
|
+
end
|
112
|
+
|
113
|
+
parts.join("")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module VirtualBox
|
2
|
+
module COM
|
3
|
+
module FFI
|
4
|
+
# Callback types for VBOXXPCOMC
|
5
|
+
callback :pfnGetVersion, [], :uint
|
6
|
+
callback :pfnComInitialize, [:string, :pointer, :string, :pointer], :void
|
7
|
+
callback :pfnComUninitialize, [], :void
|
8
|
+
callback :pfnComUnallocMem, [:pointer], :void
|
9
|
+
callback :pfnUtf16Free, [:pointer], :void
|
10
|
+
callback :pfnUtf8Free, [:string], :void
|
11
|
+
callback :pfnUtf16ToUtf8, [:pointer, :pointer], :int
|
12
|
+
callback :pfnUtf8ToUtf16, [:string, :pointer], :int
|
13
|
+
callback :pfnGetEventQueue, [:pointer], :void
|
14
|
+
|
15
|
+
class VBOXXPCOMC < ::FFI::Struct
|
16
|
+
layout :cb, :uint,
|
17
|
+
:uVersion, :uint,
|
18
|
+
:pfnGetVersion, :pfnGetVersion,
|
19
|
+
:pfnComInitialize, :pfnComInitialize,
|
20
|
+
:pfnComUninitialize, :pfnComUninitialize,
|
21
|
+
:pfnComUnallocMem, :pfnComUnallocMem,
|
22
|
+
:pfnUtf16Free, :pfnUtf16Free,
|
23
|
+
:pfnUtf8Free, :pfnUtf8Free,
|
24
|
+
:pfnUtf16ToUtf8, :pfnUtf16ToUtf8,
|
25
|
+
:pfnUtf8ToUtf16, :pfnUtf8ToUtf16,
|
26
|
+
:pfnGetEventQueue, :pfnGetEventQueue,
|
27
|
+
:uEndVersion, :uint
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module VirtualBox
|
2
|
+
module COM
|
3
|
+
class FFIInterface < BaseInterface
|
4
|
+
extend ::FFI::Library
|
5
|
+
include Logger
|
6
|
+
|
7
|
+
# Constant used to initialize the XPCOM C interface
|
8
|
+
XPCOMC_VERSION = 0x00020000
|
9
|
+
|
10
|
+
# VBOXXPCOMC struct. This typically won't be used.
|
11
|
+
attr_reader :xpcom
|
12
|
+
|
13
|
+
# The VirtualBox and Session interfaces, both of which are extremely
|
14
|
+
# important in interfacing with the VirtualBox API. Once these have been
|
15
|
+
# initialized, all other parts of the API can be accessed via these
|
16
|
+
# instances.
|
17
|
+
attr_reader :virtualbox
|
18
|
+
attr_reader :session
|
19
|
+
|
20
|
+
class << self
|
21
|
+
# Sets up the FFI interface and also initializes the interface,
|
22
|
+
# returning an instance of {FFIInterface}.
|
23
|
+
def create(lib_path=nil)
|
24
|
+
setup(lib_path)
|
25
|
+
new
|
26
|
+
end
|
27
|
+
|
28
|
+
# Sets up the FFI interface by specifying the FFI library path
|
29
|
+
# and attaching the initial function (which can't be done until
|
30
|
+
# the FFI library is specified).
|
31
|
+
#
|
32
|
+
# @param [String] lib_path
|
33
|
+
def setup(lib_path=nil)
|
34
|
+
# Setup the path to the C library
|
35
|
+
lib_path ||= "/Applications/VirtualBox.app/Contents/MacOS/VBoxXPCOMC.dylib"
|
36
|
+
|
37
|
+
# Attach to the interface
|
38
|
+
ffi_lib lib_path
|
39
|
+
attach_function :VBoxGetXPCOMCFunctions, [:uint], :pointer
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def initialize
|
44
|
+
super
|
45
|
+
initialize_com
|
46
|
+
end
|
47
|
+
|
48
|
+
# Initializes the COM interface with XPCOM. This sets up the `virtualbox`,
|
49
|
+
# `session`, and `xpcom` attributes. This should only be called once.
|
50
|
+
def initialize_com
|
51
|
+
# Get the pointer to the XPCOMC struct which contains the functions
|
52
|
+
# to initialize
|
53
|
+
xpcom_pointer = self.class.VBoxGetXPCOMCFunctions(XPCOMC_VERSION)
|
54
|
+
@xpcom = FFI::VBOXXPCOMC.new(xpcom_pointer)
|
55
|
+
|
56
|
+
initialize_singletons
|
57
|
+
end
|
58
|
+
|
59
|
+
# Initializes the VirtualBox and Session interfaces. It goes through
|
60
|
+
# the various directories until it finds a working pair.
|
61
|
+
def initialize_singletons
|
62
|
+
interface_dir = File.expand_path(File.join(File.dirname(__FILE__), "interface"))
|
63
|
+
Dir[File.join(interface_dir, "*")].each do |f|
|
64
|
+
if File.directory?(f)
|
65
|
+
return if initialize_for_version(File.basename(f))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Initializes the FFI interface for a specific version.
|
71
|
+
def initialize_for_version(version)
|
72
|
+
logger.debug("FFI init: Trying version #{version}")
|
73
|
+
|
74
|
+
# Setup the FFI classes
|
75
|
+
VirtualBox::COM::FFI.setup(version)
|
76
|
+
virtualbox_klass = COM::Util.versioned_interface(:VirtualBox)
|
77
|
+
session_klass = COM::Util.versioned_interface(:Session)
|
78
|
+
|
79
|
+
# Setup the OUT pointers
|
80
|
+
virtualbox_ptr = ::FFI::MemoryPointer.new(:pointer)
|
81
|
+
session_ptr = ::FFI::MemoryPointer.new(:pointer)
|
82
|
+
|
83
|
+
# Call the initialization functions
|
84
|
+
@xpcom[:pfnComInitialize].call(virtualbox_klass::IID_STR, virtualbox_ptr, session_klass::IID_STR, session_ptr)
|
85
|
+
@virtualbox = virtualbox_klass.new(Implementer::FFI, self, virtualbox_ptr.get_pointer(0))
|
86
|
+
@session = session_klass.new(Implementer::FFI, self, session_ptr.get_pointer(0))
|
87
|
+
|
88
|
+
logger.debug(" -- Valid version")
|
89
|
+
true
|
90
|
+
rescue Exception => e
|
91
|
+
logger.debug(" -- Invalid version")
|
92
|
+
false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|