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