diff VBoxFrontend/VBoxXPCOM.cs @ 0:e1ec7bf71313

Initial commit
author Ivo Smits
date Wed, 04 May 2011 00:59:43 +0200
parents
children f1deea9c97a0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VBoxFrontend/VBoxXPCOM.cs	Wed May 04 00:59:43 2011 +0200
@@ -0,0 +1,124 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using VirtualBox;
+
+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 delegate void pfnComUninitializeDelegate();
+		private delegate void pfnGetEventQueueDelegate(out IntPtr eventQueue); //void  (*pfnGetEventQueue)(nsIEventQueue **eventQueue);
+
+		private struct VBOXXPCOMC {
+			public UInt32 cb; //The size of the structure.
+			public UInt32 uVersion; //The structure version.
+			[MarshalAs(UnmanagedType.FunctionPtr)]
+			public pfnGetVersionDelegate pfnGetVersion;
+			[MarshalAs(UnmanagedType.FunctionPtr)]
+			public pfnComInitializeDelegate pfnComInitialize;
+			[MarshalAs(UnmanagedType.FunctionPtr)]
+			public pfnComUninitializeDelegate pfnComUninitialize;
+			[MarshalAs(UnmanagedType.FunctionPtr)]
+			private pfnComUninitializeDelegate pfnComUnallocMem; //void  (*pfnComUnallocMem)(void *pv);
+			[MarshalAs(UnmanagedType.FunctionPtr)]
+			private pfnComUninitializeDelegate pfnUtf16Free; //void  (*pfnUtf16Free)(PRUnichar *pwszString);
+			[MarshalAs(UnmanagedType.FunctionPtr)]
+			private pfnComUninitializeDelegate pfnUtf8Free; //void  (*pfnUtf8Free)(char *pszString);
+			[MarshalAs(UnmanagedType.FunctionPtr)]
+			private pfnComUninitializeDelegate pfnUtf16ToUtf8; //int   (*pfnUtf16ToUtf8)(const PRUnichar *pwszString, char **ppszString);
+			[MarshalAs(UnmanagedType.FunctionPtr)]
+			private pfnComUninitializeDelegate pfnUtf8ToUtf16; //int   (*pfnUtf8ToUtf16)(const char *pszString, PRUnichar **ppwszString);
+			[MarshalAs(UnmanagedType.FunctionPtr)]
+			public pfnGetEventQueueDelegate pfnGetEventQueue; //void  (*pfnGetEventQueue)(nsIEventQueue **eventQueue);
+			public UInt32 uEndVersion; //Tail version, same as uVersion.
+		}
+
+		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+		[Guid("176afb41-00a4-11d3-9f2a-00400553eef0")]
+		[ComImport()]
+		public interface nsIEventQueue {
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void PostEvent(IntPtr aEvent); //[noscript] void postEvent (in PLEventPtr aEvent);
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			Int32 IsOnCurrentThread(); //boolean isOnCurrentThread ();
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void InitEvent(IntPtr aEvent, IntPtr owner, IntPtr handler, IntPtr destructor); //[noscript] void initEvent (in PLEventPtr aEvent, in voidPtr owner, in PLHandleEventProc handler, in PLDestroyEventProc destructor);
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void PostSynchronousEvent(IntPtr aEvent, out IntPtr aResult); //[noscript] void postSynchronousEvent (in PLEventPtr aEvent, out voidPtr aResult);
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			Int32 PendingEvents(); //boolean pendingEvents ();
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void ProcessPendingEvents(); //void processPendingEvents ();
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void EventLoop(); //void eventLoop ();
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void EventAvailable(ref Int32 aResult); //[noscript] void eventAvailable (in PRBoolRef aResult);
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			IntPtr GetEvent(); //[noscript] PLEventPtr getEvent ();
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void HandleEvent(IntPtr aEvent); //[noscript] void handleEvent (in PLEventPtr aEvent);
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			IntPtr WaitForEvent(); //[noscript] PLEventPtr waitForEvent ();
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			Int32 GetEventQueueSelectFD(); //[notxpcom] PRInt32 getEventQueueSelectFD ();
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void Init(Int32 aNative); //void init (in boolean aNative);
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void InitFromPRThread(IntPtr thread, Int32 aNative); //[noscript] void initFromPRThread (in PRThreadPtr thread, in boolean aNative);
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void InitFromPLQueue(IntPtr aQueue); //[noscript] void initFromPLQueue (in PLEventQueuePtr aQueue);
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void EnterMonitor(); //void enterMonitor ();
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void ExitMonitor(); //void exitMonitor ();
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void RevokeEvents(IntPtr owner); //[noscript] void revokeEvents (in voidPtr owner);
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			IntPtr GetPLEventQueue(); //[noscript] PLEventQueuePtr getPLEventQueue ();
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			Int32 IsQueueNative(); //boolean isQueueNative ();
+			[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+			void StopAcceptingEvents(); //void stopAcceptingEvents ();
+		}
+
+		public const UInt32 VBOX_XPCOMC_VERSION = 0x00020000U;
+		[DllImport("/usr/lib/virtualbox/VBoxXPCOMC.so")]
+		public static extern IntPtr VBoxGetXPCOMCFunctions(UInt32 uVersion);
+
+		private VBOXXPCOMC FunctionTable;
+		public IVirtualBox VirtualBox { get; private set; }
+		public ISession Session { get; private set; }
+		public nsIEventQueue EventQueue { get; private set; }
+
+		//[STAThread]
+		public VBoxXPCOM() {
+			IntPtr ftptr = VBoxGetXPCOMCFunctions(VBOX_XPCOMC_VERSION);
+			//Console.WriteLine("Function table={0}", ftptr);
+
+			FunctionTable = (VBOXXPCOMC)Marshal.PtrToStructure(ftptr, typeof(VBOXXPCOMC));
+			//Console.WriteLine("Version {0}={1}={2}", VBOX_XPCOMC_VERSION, FunctionTable.uVersion, FunctionTable.uEndVersion);
+			//Console.WriteLine("Version {0}", FunctionTable.pfnGetVersion());
+
+			IntPtr vbptr, sessptr, eqptr;
+			FunctionTable.pfnComInitialize("D2DE270C-1D4B-4C9E-843F-BBB9B47269FF", out vbptr, "12F4DCDB-12B2-4EC1-B7CD-DDD9F6C5BF4D", out sessptr);
+			FunctionTable.pfnGetEventQueue(out eqptr);
+			//Console.WriteLine("VirtualBox={0} Session={1} EventQueue={2}", vbptr, sessptr, eqptr);
+
+			VirtualBox = (IVirtualBox)Marshal.GetObjectForIUnknown(vbptr);
+			Session = (ISession)Marshal.GetObjectForIUnknown(sessptr);
+			EventQueue = (nsIEventQueue)Marshal.GetObjectForIUnknown(eqptr);
+		}
+		~VBoxXPCOM() {
+			VirtualBox = null;
+			Session = null;
+			EventQueue = null;
+			GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
+			FunctionTable.pfnComUninitialize();
+		}
+	}
+}
\ No newline at end of file