changeset 2:f1deea9c97a0

Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
author Ivo Smits
date Wed, 04 May 2011 16:10:08 +0200
parents 55ca098c88d0
children b0033e69105a
files InteropCodeGen/gendotnet.cs VBoxFrontend/VBoxFrontend.csproj VBoxFrontend/VBoxMono.c VBoxFrontend/VBoxXPCOM.cs
diffstat 4 files changed, 107 insertions(+), 188 deletions(-) [+]
line wrap: on
line diff
--- a/InteropCodeGen/gendotnet.cs	Wed May 04 01:06:22 2011 +0200
+++ b/InteropCodeGen/gendotnet.cs	Wed May 04 16:10:08 2011 +0200
@@ -15,29 +15,16 @@
 	class TypeInfo {
 		public String Name { get; private set; }
 		public String[] Attributes { get; private set; }
-		//public Boolean InputOnly { get; private set; }
-		public String Members { get; set; }
 
 		public TypeInfo(String name, params String[] attributes) {
 			this.Name = name;
 			this.Attributes = attributes;
 		}
-		/*public TypeInfo(String name, bool inputOnly, params String[] attributes)
-			: this(name, attributes) {
-			this.InputOnly = inputOnly;
-		}*/
-		/*public static TypeInfo CreateInterfaceWithMembers(String name, String members) {
-			TypeInfo ret = new TypeInfo(name, "MarshalAs(UnmanagedType.Interface)");
-			ret.Members = members;
-			return ret;
-		}*/
-		//Todo: if attribute mod="string"/"ptr" ...
 		public void WriteDeclaration(TextWriter o, ParameterType vartype) {
 			WriteAttributes(o, vartype);
 			o.Write(Name);
 		}
 		public void WriteAttributes(TextWriter o, ParameterType vartype) {
-			//if (InputOnly && vartype != ParameterType.In) {
 			foreach (String attribute in Attributes) {
 				o.Write("[");
 				if (vartype == ParameterType.Return) o.Write("return: ");
@@ -50,6 +37,12 @@
 		}
 	}
 	static Dictionary<String, TypeInfo> Types = new Dictionary<string, TypeInfo>();
+	static void AddInterfaceTypes(params String[] names) {
+		foreach (String name in names) Types.Add(name, new TypeInfo(name, "MarshalAs(UnmanagedType.Interface)"));
+	}
+	static void AddEnumTypes(params String[] names) {
+		foreach (String name in names) Types.Add(name, new TypeInfo(name));
+	}
 	static void InitTypes() {
 		Types.Add("short", new TypeInfo("Int16"));
 		Types.Add("unsigned short", new TypeInfo("UInt16"));
@@ -63,119 +56,31 @@
 		Types.Add("wstring", new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)"));
 		//Types.Add("uuid", new TypeInfo("Guid", true, "MarshalAs(UnmanagedType.LPStruct)"));
 		Types.Add("uuid", new TypeInfo("Guid", "MarshalAs(UnmanagedType.LPStruct)"));
-
-		Types.Add("IMachine", new TypeInfo("IMachine", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("ISession", new TypeInfo("ISession", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IVirtualBox", new TypeInfo("IVirtualBox", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IHost", new TypeInfo("IHost", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IConsole", new TypeInfo("IConsole", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("ISystemProperties", new TypeInfo("ISystemProperties", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IProgress", new TypeInfo("IProgress", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IDisplay", new TypeInfo("IDisplay", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IMouse", new TypeInfo("IMouse", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IKeyboard", new TypeInfo("IKeyboard", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IFramebuffer", new TypeInfo("IFramebuffer", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IFramebufferOverlay", new TypeInfo("IFramebufferOverlay", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IMachineDebugger", new TypeInfo("IMachineDebugger", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IVirtualBoxErrorInfo", new TypeInfo("IVirtualBoxErrorInfo", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IEventSource", new TypeInfo("IEventSource", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IEventListener", new TypeInfo("IEventListener", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IEventContext", new TypeInfo("IEventContext", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IConsoleCallback", new TypeInfo("IConsoleCallback", "MarshalAs(UnmanagedType.Interface)"));
-		Types.Add("IEvent", new TypeInfo("IEvent", "MarshalAs(UnmanagedType.Interface)"));
+		Types.Add("$unknown", new TypeInfo("IntPtr"));
 
-		Types.Add("LockType", new TypeInfo("LockType"));
-		Types.Add("MediumVariant", new TypeInfo("MediumVariant"));
-		Types.Add("AccessMode", new TypeInfo("AccessMode"));
-		Types.Add("NATProtocol", new TypeInfo("NATProtocol"));
-		Types.Add("FirmwareType", new TypeInfo("FirmwareType"));
-		Types.Add("StorageControllerType", new TypeInfo("StorageControllerType"));
-		Types.Add("StorageBus", new TypeInfo("StorageBus"));
-		Types.Add("SessionType", new TypeInfo("SessionType"));
-		Types.Add("SessionState", new TypeInfo("SessionState"));
-		Types.Add("USBDeviceState", new TypeInfo("USBDeviceState"));
-		Types.Add("USBDeviceFilterAction", new TypeInfo("USBDeviceFilterAction"));
-		Types.Add("AudioControllerType", new TypeInfo("AudioControllerType"));
-		Types.Add("AudioDriverType", new TypeInfo("AudioDriverType"));
-		Types.Add("VRDPAuthType", new TypeInfo("VRDPAuthType"));
-		Types.Add("MachineState", new TypeInfo("MachineState"));
-		Types.Add("NetworkAdapterType", new TypeInfo("NetworkAdapterType"));
-		Types.Add("NetworkAttachmentType", new TypeInfo("NetworkAttachmentType"));
-		Types.Add("PortMode", new TypeInfo("PortMode"));
-		Types.Add("DeviceType", new TypeInfo("DeviceType"));
-		Types.Add("MediumState", new TypeInfo("MediumState"));
-		Types.Add("MediumType", new TypeInfo("MediumType"));
-		Types.Add("HostNetworkInterfaceType", new TypeInfo("HostNetworkInterfaceType"));
-		Types.Add("DeviceActivity", new TypeInfo("DeviceActivity"));
-		Types.Add("HostNetworkInterfaceMediumType", new TypeInfo("HostNetworkInterfaceMediumType"));
-		Types.Add("HostNetworkInterfaceStatus", new TypeInfo("HostNetworkInterfaceStatus"));
-		Types.Add("ProcessorFeature", new TypeInfo("ProcessorFeature"));
-		Types.Add("VFSType", new TypeInfo("VFSType"));
-		Types.Add("BIOSBootMenuMode", new TypeInfo("BIOSBootMenuMode"));
-		Types.Add("VirtualSystemDescriptionType", new TypeInfo("VirtualSystemDescriptionType"));
-		Types.Add("VirtualSystemDescriptionValueType", new TypeInfo("VirtualSystemDescriptionValueType"));
-		Types.Add("KeyboardHidType", new TypeInfo("KeyboardHidType"));
-		Types.Add("ClipboardMode", new TypeInfo("ClipboardMode"));
-		Types.Add("PointingHidType", new TypeInfo("PointingHidType"));
-		Types.Add("CPUPropertyType", new TypeInfo("CPUPropertyType"));
-		Types.Add("HWVirtExPropertyType", new TypeInfo("HWVirtExPropertyType"));
-		Types.Add("Scope", new TypeInfo("Scope"));
-		Types.Add("ChipsetType", new TypeInfo("ChipsetType"));
-		Types.Add("FaultToleranceState", new TypeInfo("FaultToleranceState"));
-		Types.Add("BandwidthGroupType", new TypeInfo("BandwidthGroupType"));
-		Types.Add("VBoxEventType", new TypeInfo("VBoxEventType"));
-		Types.Add("GuestMonitorChangedEventType", new TypeInfo("GuestMonitorChangedEventType"));
-		Types.Add("AuthType", new TypeInfo("AuthType"));
-		Types.Add("NetworkAdapterPromiscModePolicy", new TypeInfo("NetworkAdapterPromiscModePolicy"));
-		Types.Add("ExecuteProcessStatus", new TypeInfo("ExecuteProcessStatus"));
-		Types.Add("AdditionsRunLevelType", new TypeInfo("AdditionsRunLevelType"));
-		Types.Add("AdditionsFacilityStatus", new TypeInfo("AdditionsFacilityStatus"));
-		Types.Add("AdditionsFacilityType", new TypeInfo("AdditionsFacilityType"));
-		Types.Add("AdditionsFacilityClass", new TypeInfo("AdditionsFacilityClass"));
-		Types.Add("CleanupMode", new TypeInfo("CleanupMode"));
-		Types.Add("DataType", new TypeInfo("DataType"));
-
-		Types.Add("IBandwidthControl", new TypeInfo("IntPtr"));
-		Types.Add("IVRDEServerInfo", new TypeInfo("IntPtr"));
-		Types.Add("IAdditionsFacility", new TypeInfo("IntPtr"));
-		Types.Add("IExtPackPlugIn", new TypeInfo("IntPtr"));
-		Types.Add("IExtPackFile", new TypeInfo("IntPtr"));
-		Types.Add("IExtPack", new TypeInfo("IntPtr"));
-		Types.Add("IBIOSSettings", new TypeInfo("IntPtr"));
-		Types.Add("IVFSExplorer", new TypeInfo("IntPtr"));
-		Types.Add("IUSBController", new TypeInfo("IntPtr"));
-		Types.Add("IStorageController", new TypeInfo("IntPtr"));
-		Types.Add("IVRDPServer", new TypeInfo("IntPtr"));
-		Types.Add("ISnapshot", new TypeInfo("IntPtr"));
-		Types.Add("INATEngine", new TypeInfo("IntPtr"));
-		Types.Add("IUSBDeviceFilter", new TypeInfo("IntPtr"));
-		Types.Add("IMediumAttachment", new TypeInfo("IntPtr"));
-		Types.Add("IUSBDevice", new TypeInfo("IntPtr"));
-		Types.Add("IParallelPort", new TypeInfo("IntPtr"));
-		Types.Add("ISerialPort", new TypeInfo("IntPtr"));
-		Types.Add("INetworkAdapter", new TypeInfo("IntPtr"));
-		Types.Add("IMedium", new TypeInfo("IntPtr"));
-		Types.Add("IGuestOSType", new TypeInfo("IntPtr"));
-		Types.Add("ISharedFolder", new TypeInfo("IntPtr"));
-		Types.Add("IPerformanceCollector", new TypeInfo("IntPtr"));
-		Types.Add("IDHCPServer", new TypeInfo("IntPtr"));
-		Types.Add("IAppliance", new TypeInfo("IntPtr"));
-		Types.Add("IVirtualBoxCallback", new TypeInfo("IntPtr"));
-		Types.Add("IPerformanceMetric", new TypeInfo("IntPtr"));
-		Types.Add("IMediumFormat", new TypeInfo("IntPtr"));
-		Types.Add("IHostUSBDevice", new TypeInfo("IntPtr"));
-		Types.Add("IHostNetworkInterface", new TypeInfo("IntPtr"));
-		Types.Add("IHostUSBDeviceFilter", new TypeInfo("IntPtr"));
-		Types.Add("IRemoteDisplayInfo", new TypeInfo("IntPtr"));
-		Types.Add("IGuest", new TypeInfo("IntPtr"));
-		Types.Add("IVirtualSystemDescription", new TypeInfo("IntPtr"));
-		Types.Add("IAudioAdapter", new TypeInfo("IntPtr"));
-		Types.Add("IExtPackManager", new TypeInfo("IntPtr"));
-		Types.Add("IVRDEServer", new TypeInfo("IntPtr"));
-		Types.Add("IPciDeviceAttachment", new TypeInfo("IntPtr"));
-		Types.Add("IBandwidthGroup", new TypeInfo("IntPtr"));
-
-		Types.Add("$unknown", new TypeInfo("IntPtr"));
+		AddInterfaceTypes("IMachine", "ISession", "IVirtualBox", "IHost", "IConsole", "ISystemProperties");
+		AddInterfaceTypes("IProgress", "IDisplay", "IMouse", "IKeyboard", "IFramebuffer", "IFramebufferOverlay");
+		AddInterfaceTypes("IMachineDebugger", "IVirtualBoxErrorInfo", "IEventSource", "IEventListener", "IEventContext");
+		AddInterfaceTypes("IConsoleCallback", "IEvent", "IBandwidthControl", "IVRDEServerInfo", "IAdditionsFacility");
+		AddInterfaceTypes("IExtPackPlugIn", "IExtPackFile", "IExtPack", "IBIOSSettings", "IVFSExplorer", "IUSBController");
+		AddInterfaceTypes("IStorageController", "IVRDPServer", "ISnapshot", "INATEngine", "IUSBDeviceFilter");
+		AddInterfaceTypes("IMediumAttachment", "IUSBDevice", "IParallelPort", "ISerialPort", "INetworkAdapter");
+		AddInterfaceTypes("IMedium", "IGuestOSType", "ISharedFolder", "IPerformanceCollector", "IDHCPServer");
+		AddInterfaceTypes("IAppliance", "IVirtualBoxCallback", "IPerformanceMetric", "IMediumFormat", "IHostUSBDevice");
+		AddInterfaceTypes("IHostNetworkInterface", "IHostUSBDeviceFilter", "IRemoteDisplayInfo", "IGuest");
+		AddInterfaceTypes("IVirtualSystemDescription", "IAudioAdapter", "IExtPackManager", "IVRDEServer");
+		AddInterfaceTypes("IPciDeviceAttachment", "IBandwidthGroup");
+	
+		AddEnumTypes("LockType", "MediumVariant", "AccessMode", "NATProtocol", "FirmwareType", "StorageControllerType");
+		AddEnumTypes("StorageBus", "SessionType", "SessionState", "USBDeviceState", "USBDeviceFilterAction");
+		AddEnumTypes("AudioControllerType", "AudioDriverType", "VRDPAuthType", "MachineState", "NetworkAdapterType");
+		AddEnumTypes("NetworkAttachmentType", "PortMode", "DeviceType", "MediumState", "VFSType", "MediumType");
+		AddEnumTypes("HostNetworkInterfaceType", "DeviceActivity", "HostNetworkInterfaceMediumType", "HostNetworkInterfaceStatus");
+		AddEnumTypes("ProcessorFeature", "BIOSBootMenuMode", "VirtualSystemDescriptionType", "VirtualSystemDescriptionValueType");
+		AddEnumTypes("KeyboardHidType", "ClipboardMode", "PointingHidType", "CPUPropertyType", "HWVirtExPropertyType");
+		AddEnumTypes("ChipsetType", "FaultToleranceState", "BandwidthGroupType", "ExecuteProcessStatus", "VBoxEventType");
+		AddEnumTypes("GuestMonitorChangedEventType", "AuthType", "NetworkAdapterPromiscModePolicy", "AdditionsRunLevelType");
+		AddEnumTypes("AdditionsFacilityStatus", "AdditionsFacilityType", "AdditionsFacilityClass", "CleanupMode", "DataType");
 	}
 	static void Main(string[] args) {
 		InitTypes();
@@ -243,27 +148,10 @@
 					break;
 				case "attribute": {
 						String mName = member.SelectSingleNode("@name").Value;
-						//String mType = member.SelectSingleNode("@type").Value;
 						item = member.SelectSingleNode("@readonly");
 						Boolean mReadOnly = item == null ? false : item.Value == "yes";
-						//item = member.SelectSingleNode("@mod");
-						//String mMod = item == null ? null : item.Value;
 						mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1);
 						oattribute.Write("\t");
-						/*TypeInfo t;
-						if (mMod == "ptr") {
-							t = new TypeInfo("IntPtr");
-						} else if (mMod == "string") {
-							t = new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)");
-						} else if (mMod == null) {
-							if (!Types.TryGetValue(mType, out t)) {
-								Console.Error.WriteLine("Type {0} is not supported", mType);
-								t = new TypeInfo("void");
-							}
-						} else {
-							Console.Error.WriteLine("Type modifier {0} is not supported", mMod);
-							t = new TypeInfo("void");
-						}*/
 						TypeInfo t = GetTypeDeclaration(member);
 						oattribute.Write(t.Name);
 						oattribute.Write(" ");
@@ -290,15 +178,7 @@
 						} else {
 							mParamReturn.MoveNext();
 							mReturn = true;
-							TypeInfo t = GetTypeDeclaration(mParamReturn.Current);
-							/*String mType = mParamReturn.Current.SelectSingleNode("@type").Value;
-							TypeInfo t;
-							if (!Types.TryGetValue(mType, out t)) {
-								Console.Error.WriteLine("Type {0} is not supported", mType);
-								t = new TypeInfo("void");
-								mReturn = false;
-							}*/
-							t.WriteDeclaration(omethod, ParameterType.Return);
+							WriteTypeDeclaration(omethod, mParamReturn.Current, ParameterType.Return);
 						}
 						mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1);
 						omethod.Write(" ");
@@ -310,10 +190,6 @@
 							while (true) {
 								XPathNavigator mParam = mParams.Current;
 								String pDir = mParam.SelectSingleNode("@dir").Value;
-								//item = mParam.SelectSingleNode("@safearray");
-								//Boolean pArray = item == null ? false : item.Value == "yes";
-								//item = mParam.SelectSingleNode("@mod");
-								//String pMod = item == null ? null : item.Value;
 								if (pDir == "return" && mReturn) {
 									if (mParams.MoveNext()) {
 										continue;
@@ -330,31 +206,7 @@
 								} else {
 									omethod.Write(", ");
 								}
-								ParameterType pt = ParameterType.In;
-								if (pDir == "out") pt = ParameterType.Out;
-								TypeInfo t = GetTypeDeclaration(mParam, ref pt);
-								t.WriteDeclaration(omethod, pt);
-								/*if (pArray) {
-									omethod.Write("[MarshalAs(UnmanagedType.SafeArray)] ");
-									if (pDir == "out") omethod.Write("out ");
-									else omethod.Write("ref ");
-									omethod.Write("System.Array");
-								} else {
-									String pType = mParam.SelectSingleNode("@type").Value;
-									TypeInfo t;
-									if (!Types.TryGetValue(pType, out t)) {
-										Console.Error.WriteLine("Type {0} is not supported", pType);
-										t = new TypeInfo("IntPtr");
-										mReturn = false;
-									}
-									if (pMod == "ptr") {
-										t.WriteDeclaration(omethod, ParameterType.Reference);
-									} else if (pDir == "out") {
-										t.WriteDeclaration(omethod, ParameterType.Out);
-									} else {
-										t.WriteDeclaration(omethod, ParameterType.In);
-									}
-								}*/
+								WriteTypeDeclaration(omethod, mParam, pDir == "out" ? ParameterType.Out : ParameterType.In);
 								omethod.Write(" p");
 								omethod.Write(mParam.SelectSingleNode("@name").Value);
 								if (!mParams.MoveNext()) break;
@@ -373,6 +225,10 @@
 		ParameterType pt = ParameterType.Param;
 		return GetTypeDeclaration(nav, ref pt);
 	}
+	private static void WriteTypeDeclaration(TextWriter o, XPathNavigator nav, ParameterType paramType) {
+		TypeInfo t = GetTypeDeclaration(nav, ref paramType);
+		t.WriteDeclaration(o, paramType);
+	}
 	private static TypeInfo GetTypeDeclaration(XPathNavigator nav, ref ParameterType paramType) {
 		String mType = nav.SelectSingleNode("@type").Value;
 		XPathItem item;
--- a/VBoxFrontend/VBoxFrontend.csproj	Wed May 04 01:06:22 2011 +0200
+++ b/VBoxFrontend/VBoxFrontend.csproj	Wed May 04 16:10:08 2011 +0200
@@ -83,6 +83,9 @@
       <LastGenOutput>Resources.Designer.cs</LastGenOutput>
     </EmbeddedResource>
   </ItemGroup>
+  <ItemGroup>
+    <Content Include="VBoxMono.c" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VBoxFrontend/VBoxMono.c	Wed May 04 16:10:08 2011 +0200
@@ -0,0 +1,62 @@
+/* To compile, you may have to specify:
+ *  The include paths for mono: -I /usr/include/mono-1.0/ -I /usr/include/glib-2.0/ -I /usr/lib/glib-2.0/include/
+ *  The location of the VBoxXPCOMC.so library: /usr/lib/virtualbox/VBoxXPCOMC.so
+ *  The location of the mono library (if an alternative build is to be used): /home/ivo/mono/devtest/lib/libmono-2.0.so
+ *  To link against the mono library (if the system wide installed version is to be used): -lmono
+ *  Where to look for the VBoxXPCOMC.so library at run time: -Wl,-R,/usr/lib/virtualbox
+ *  Where to look for the mono library at run time (if non-standard): -R,/home/ivo/mono/devtest/lib/
+ *
+ * The resulting commandline may look like this:
+   gcc VBoxMono.c -o VBoxMono -lmono \
+    -I /usr/include/mono-1.0/ -I /usr/include/glib-2.0/ -I /usr/lib/glib-2.0/include/ \
+    /usr/lib/virtualbox/VBoxXPCOMC.so -Wl,-R,/usr/lib/virtualbox
+ * The resulting commandline may look like this if mono is installed in an alternative location:
+   gcc VBoxMono.c -o VBoxMono \
+    -I /usr/include/mono-1.0/ -I /usr/include/glib-2.0/ -I /usr/lib/glib-2.0/include/ \
+    /usr/lib/virtualbox/VBoxXPCOMC.so -Wl,-R,/usr/lib/virtualbox \
+    /home/ivo/mono/devtest/lib/libmono-2.0.so -Wl,-R,/home/ivo/mono/devtest/lib/
+ * Then make the binary owned by root and set the suid bit:
+   sudo chown root VBoxMono
+   sudo chmod u+s VBoxMono
+*/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <mono/jit/jit.h>
+#include <mono/metadata/assembly.h>
+#include <mono/metadata/mono-config.h>
+
+extern int RTR3InitAndSUPLib();
+
+int main(int argc, char *argv[]) {
+        if (argc < 2) {
+                fprintf(stderr, "VBoxMono: Usage: %s assembly.exe\n", argv[0]);
+                return 1;
+        }
+        int rc = RTR3InitAndSUPLib();
+        if (rc != 0) {
+                fprintf(stderr, "VBoxMono: Could not initialize VirtualBox driver (%d)\n", rc);
+                return rc;
+        }
+        int gid = getuid();
+        if (gid != getegid()) setregid(gid, gid);
+        int uid = getuid();
+        if (uid != geteuid()) setreuid(uid, uid);
+        mono_config_parse(NULL);
+        //mono_set_dirs("/home/ivo/mono/devtest/lib", "/etc");
+        MonoDomain *domain = mono_jit_init_version("VirtualBox", "v2.0.50727");
+        if (!domain) {
+                fprintf(stderr, "VBoxMono: Could not create application domain\n");
+                return 1;
+        }
+        MonoAssembly *assembly = mono_domain_assembly_open(domain, argv[1]);
+        if (!assembly) {
+                fprintf(stderr, "VBoxMono: Could not load assembly %s\n", argv[1]);
+                mono_jit_cleanup(domain);
+                return 1;
+        }
+        int ret = mono_jit_exec(domain, assembly, argc - 1, argv + 1);
+        mono_jit_cleanup(domain);
+        return ret;
+}
--- a/VBoxFrontend/VBoxXPCOM.cs	Wed May 04 01:06:22 2011 +0200
+++ b/VBoxFrontend/VBoxXPCOM.cs	Wed May 04 16:10:08 2011 +0200
@@ -6,13 +6,10 @@
 namespace ConsoleApplication1 {
 	public class VBoxXPCOM {
 		private delegate UInt32 pfnGetVersionDelegate();
-		private unsafe delegate void pfnComInitializeDelegate(
-			[MarshalAs(UnmanagedType.LPStr)] String pszVirtualBoxIID,
-			out IntPtr ppVirtualBox,
-			[MarshalAs(UnmanagedType.LPStr)] String pszSessionIID,
-			out IntPtr ppSession);
+		private unsafe delegate void pfnComInitializeDelegate([MarshalAs(UnmanagedType.LPStr)] String pszVirtualBoxIID, out IntPtr ppVirtualBox, [MarshalAs(UnmanagedType.LPStr)] String pszSessionIID, out IntPtr ppSession);
 		private delegate void pfnComUninitializeDelegate();
 		private delegate void pfnGetEventQueueDelegate(out IntPtr eventQueue); //void  (*pfnGetEventQueue)(nsIEventQueue **eventQueue);
+		private delegate void pfnComUnallocMem(IntPtr pv); //void  (*pfnComUnallocMem)(void *pv);
 
 		private struct VBOXXPCOMC {
 			public UInt32 cb; //The size of the structure.
@@ -24,11 +21,11 @@
 			[MarshalAs(UnmanagedType.FunctionPtr)]
 			public pfnComUninitializeDelegate pfnComUninitialize;
 			[MarshalAs(UnmanagedType.FunctionPtr)]
-			private pfnComUninitializeDelegate pfnComUnallocMem; //void  (*pfnComUnallocMem)(void *pv);
+			private pfnComUnallocMem pfnComUnallocMem;
 			[MarshalAs(UnmanagedType.FunctionPtr)]
-			private pfnComUninitializeDelegate pfnUtf16Free; //void  (*pfnUtf16Free)(PRUnichar *pwszString);
+			private pfnComUnallocMem pfnUtf16Free; //void  (*pfnUtf16Free)(PRUnichar *pwszString);
 			[MarshalAs(UnmanagedType.FunctionPtr)]
-			private pfnComUninitializeDelegate pfnUtf8Free; //void  (*pfnUtf8Free)(char *pszString);
+			private pfnComUnallocMem pfnUtf8Free; //void  (*pfnUtf8Free)(char *pszString);
 			[MarshalAs(UnmanagedType.FunctionPtr)]
 			private pfnComUninitializeDelegate pfnUtf16ToUtf8; //int   (*pfnUtf16ToUtf8)(const PRUnichar *pwszString, char **ppszString);
 			[MarshalAs(UnmanagedType.FunctionPtr)]
@@ -118,6 +115,7 @@
 			Session = null;
 			EventQueue = null;
 			GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
+			GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
 			FunctionTable.pfnComUninitialize();
 		}
 	}