Mercurial > hg > vboxdotnet
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