bbrowning-virtualbox 0.7.6.dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|