Index: trunk/include/VBox/VBoxGuest.h
===================================================================
--- trunk/include/VBox/VBoxGuest.h	(revision 21068)
+++ trunk/include/VBox/VBoxGuest.h	(revision 21069)
@@ -62,5 +62,5 @@
 #endif
 
-#if defined(RT_OS_LINUX)
+#if defined(RT_OS_LINUX) && !defined(VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
 /** The support device name. */
 # define VBOXGUEST_DEVICE_NAME        "/dev/vboxadd"
@@ -73,10 +73,4 @@
 /** The support device name of the user accessible device node. */
 # define VBOXGUEST_USER_DEVICE_NAME   "\\Dev\\VBoxGst$"
-
-#elif defined(RT_OS_SOLARIS)
-/** The support device name. */
-# define VBOXGUEST_DEVICE_NAME        "/dev/vboxguest"
-/** The support device name of the user accessible device node. */
-# define VBOXGUEST_USER_DEVICE_NAME   "/dev/vboxguest"
 
 #elif defined(RT_OS_WINDOWS)
@@ -94,12 +88,14 @@
 # define VBOXGUEST_DEVICE_NAME_DOS    L"\\DosDevices\\VBoxGuest"
 
-#elif defined(RT_OS_FREEBSD)
+#else /* PORTME */
 /** The support device name. */
 # define VBOXGUEST_DEVICE_NAME        "/dev/vboxguest"
 /** The support device name of the user accessible device node. */
-# define VBOXGUEST_USER_DEVICE_NAME   "/dev/vboxguest"
-
-#else
-/* PORTME */
+# ifdef defined(RT_OS_LINUX)
+#  define VBOXGUEST_USER_DEVICE_NAME  "/dev/vboxuser"
+# else
+#  define VBOXGUEST_USER_DEVICE_NAME  "/dev/vboxguest"
+# endif
+
 #endif
 
Index: trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk	(revision 21068)
+++ trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk	(revision 21069)
@@ -28,5 +28,5 @@
 	$(if $(defined VBOX_WITH_OS2_ADDITIONS),os2,) \
 	$(if $(defined VBOX_WITH_ADDITION_DRIVERS),linux,) \
-	solaris) # linux is not yet using this code, just for syntax checking changes.
+	solaris)
  #
  # VBoxGuest - The Guest Additions Driver (mixed case).
@@ -43,4 +43,5 @@
  VBoxGuest_INCS          = .
  VBoxGuest_INCS.freebsd  = $(PATH_VBoxGuest)
+ VBoxGuest_INCS.linux    = ../../../Runtime/r0drv/linux
  ifneq ($(KBUILD_TARGET),os2)
   ifn1of ($(KBUILD_TARGET), linux freebsd solaris)
Index: trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c	(revision 21068)
+++ trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c	(revision 21069)
@@ -131,70 +131,4 @@
 static eventhandler_tag     g_VBoxGuestFreeBSDEHTag;
 
-/**
- * VBoxGuest Common ioctl wrapper from VBoxGuestLib.
- *
- * @returns VBox error code.
- * @param   pvSession           Opaque pointer to the session.
- * @param   uCmd                Requested function.
- * @param   pvData              IO data buffer.
- * @param   cbData              Size of the data buffer.
- * @param   pcbDataReturned     Where to store the amount of returned data.
- */
-DECLVBGL(int) VBoxGuestFreeBSDServiceCall(void *pvSession, unsigned uCmd, void *pvData, size_t cbData, size_t *pcbDataReturned)
-{
-    LogFlow((DEVICE_NAME ":VBoxGuestFreeBSDServiceCall %pvSesssion=%p uCmd=%u pvData=%p cbData=%d\n", pvSession, uCmd, pvData, cbData));
-
-    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
-    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
-    AssertMsgReturn(pSession->pDevExt == &g_DevExt,
-                    ("SC: %p != %p\n", pSession->pDevExt, &g_DevExt), VERR_INVALID_HANDLE);
-
-    return VBoxGuestCommonIOCtl(uCmd, &g_DevExt, pSession, pvData, cbData, pcbDataReturned);
-}
-
-
-/**
- * FreeBSD Guest service open.
- *
- * @returns Opaque pointer to session object.
- * @param   pu32Version         Where to store VMMDev version.
- */
-DECLVBGL(void *) VBoxGuestFreeBSDServiceOpen(uint32_t *pu32Version)
-{
-    LogFlow((DEVICE_NAME ":VBoxGuestFreeBSDServiceOpen\n"));
-
-    AssertPtrReturn(pu32Version, NULL);
-    PVBOXGUESTSESSION pSession;
-    int rc = VBoxGuestCreateKernelSession(&g_DevExt, &pSession);
-    if (RT_SUCCESS(rc))
-    {
-        *pu32Version = VMMDEV_VERSION;
-        return pSession;
-    }
-    LogRel((DEVICE_NAME ":VBoxGuestCreateKernelSession failed. rc=%d\n", rc));
-    return NULL;
-}
-
-
-/**
- * FreeBSD Guest service close.
- *
- * @returns VBox error code.
- * @param   pvState             Opaque pointer to the session object.
- */
-DECLVBGL(int) VBoxGuestFreeBSDServiceClose(void *pvSession)
-{
-    LogFlow((DEVICE_NAME ":VBoxGuestFreeBSDServiceClose\n"));
-
-    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
-    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
-    if (pSession)
-    {
-        VBoxGuestCloseSession(&g_DevExt, pSession);
-        return VINF_SUCCESS;
-    }
-    LogRel((DEVICE_NAME ":Invalid pSession.\n"));
-    return VERR_INVALID_HANDLE;
-}
 
 /**
@@ -629,4 +563,10 @@
 MODULE_VERSION(vboxguest, 1);
 
+#if 0/** @todo This shouldn't be needed. if it is, that means exceptions hasn't been disabled correctly. */
 int __gxx_personality_v0 = 0xdeadbeef;
-
+#endif
+
+
+/* Common code that depend on g_DevExt. */
+#include "VBoxGuestIDC-unix.c.h"
+
Index: trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c	(revision 21068)
+++ trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c	(revision 21069)
@@ -1,1 +1,675 @@
-/* place holder */
+/* $Rev$ */
+/** @file
+ * VBoxGuest - Linux specifics.
+ *
+ * Note. Unfortunately, the difference between this and SUPDrv-linux.c is
+ *       a little bit too big to be helpful.
+ */
+
+/*
+ * Copyright (C) 2006-2009 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ * Some lines of code to disable the local APIC on x86_64 machines taken
+ * from a Mandriva patch by Gwenole Beauchesne <gbeauchesne@mandriva.com>.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_SUP_DRV
+#include "VBoxGuestInternal.h"
+#include "the-linux-kernel.h"
+#include <linux/miscdevice.h>
+#include "version-generated.h"
+
+#include <iprt/assert.h>
+#include <iprt/spinlock.h>
+#include <iprt/semaphore.h>
+#include <iprt/initterm.h>
+#include <iprt/process.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <VBox/log.h>
+#include <iprt/mp.h>
+#include <iprt/mem.h>
+
+
+#define xstr(s) str(s)
+#define str(s) #s
+
+/** The device name. */
+#define DEVICE_NAME             "vboxguest"
+/** The device name for the device node open to everyone.. */
+#define DEVICE_NAME_USER        "vboxuser"
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+# define PCI_DEV_GET(v,d,p)     pci_get_device(v,d,p)
+# define PCI_DEV_PUT(x)         pci_dev_put(x)
+#else
+# define PCI_DEV_GET(v,d,p)     pci_find_device(v,d,p)
+# define PCI_DEV_PUT(x)         do {} while(0)
+#endif
+
+/* 2.4.x compatability macros that may or may not be defined. */
+#ifndef IRQ_RETVAL
+# define irqreturn_t            void
+# define IRQ_RETVAL(n)
+#endif
+
+
+/*******************************************************************************
+*   Internal Functions                                                         *
+*******************************************************************************/
+static int  vboxguestLinuxModInit(void);
+static void vboxguestLinuxModExit(void);
+static int  vboxguestLinuxOpen(struct inode *pInode, struct file *pFilp);
+static int  vboxguestLinuxRelease(struct inode *pInode, struct file *pFilp);
+#ifdef HAVE_UNLOCKED_IOCTL
+static long vboxguestLinuxIOCtl(struct file *pFilp, unsigned int uCmd, unsigned long ulArg);
+#else
+static int  vboxguestLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned int uCmd, unsigned long ulArg);
+#endif
+
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+/**
+ * Device extention & session data association structure.
+ */
+static VBOXGUESTDEVEXT          g_DevExt;
+/** The PCI device. */
+static struct pci_dev          *g_pPciDev;
+/** The base of the I/O port range. */
+static RTIOPORT                 g_IOPortBase;
+/** The base of the MMIO range. */
+static RTHCPHYS                 g_MMIOPhysAddr = NIL_RTHCPHYS;
+/** The size of the MMIO range as seen by PCI. */
+static uint32_t                 g_cbMMIO;
+/** The pointer to the mapping of the MMIO range. */
+static void                    *g_pvMMIOBase;
+
+/** Our file node major id.
+ * Either set dynamically at run time or statically at compile time. */
+#ifdef CONFIG_VBOXADD_MAJOR
+static unsigned int             g_iModuleMajor = CONFIG_VBOXADD_MAJOR;
+#else
+static unsigned int             g_iModuleMajor = 0;
+#endif
+
+
+/** The file_operations structure. */
+static struct file_operations   g_FileOps =
+{
+    owner:          THIS_MODULE,
+    open:           vboxguestLinuxOpen,
+    release:        vboxguestLinuxRelease,
+#ifdef HAVE_UNLOCKED_IOCTL
+    unlocked_ioctl: vboxguestLinuxIOCtl,
+#else
+    ioctl:          vboxguestLinuxIOCtl,
+#endif
+};
+
+/** The miscdevice structure. */
+static struct miscdevice        g_MiscDevice =
+{
+    minor:          MISC_DYNAMIC_MINOR,
+    name:           DEVICE_NAME,
+    fops:           &g_FileOps,
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17)
+    devfs_name:     DEVICE_NAME,
+#endif
+};
+
+/** The file_operations structure for the user device.
+ * @remarks For the time being we'll be using the same implementation as
+ *          /dev/vboxguest here. */
+static struct file_operations   g_FileOpsUser =
+{
+    owner:          THIS_MODULE,
+    open:           vboxguestLinuxOpen,
+    release:        vboxguestLinuxRelease,
+#ifdef HAVE_UNLOCKED_IOCTL
+    unlocked_ioctl: vboxguestLinuxIOCtl,
+#else
+    ioctl:          vboxguestLinuxIOCtl,
+#endif
+};
+
+/** The miscdevice structure for the user device. */
+static struct miscdevice        g_MiscDeviceUser =
+{
+    minor:          MISC_DYNAMIC_MINOR,
+    name:           DEVICE_NAME_USER,
+    fops:           &g_FileOpsUser,
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17)
+    devfs_name:     DEVICE_NAME_USER,
+#endif
+};
+
+
+/** PCI hotplug structure. */
+static const struct pci_device_id __devinitdata g_VBoxGuestPciId[] =
+{
+    {
+        vendor:     VMMDEV_VENDORID,
+        device:     VMMDEV_DEVICEID
+    },
+    {
+        /* empty entry */
+    }
+};
+MODULE_DEVICE_TABLE(pci, g_VBoxGuestPciId);
+
+
+/**
+ * Converts a VBox status code to a linux error code.
+ *
+ * @returns corresponding negative linux error code.
+ * @param   rc  supdrv error code (SUPDRV_ERR_* defines).
+ */
+static int vboxguestLinuxConvertToNegErrno(int rc)
+{
+    if (   rc > -1000
+        && rc < 1000)
+        return -RTErrConvertToErrno(rc);
+    switch (rc)
+    {
+        case VERR_HGCM_SERVICE_NOT_FOUND:      return -ESRCH;
+        case VINF_HGCM_CLIENT_REJECTED:        return 0;
+        case VERR_HGCM_INVALID_CMD_ADDRESS:    return -EFAULT;
+        case VINF_HGCM_ASYNC_EXECUTE:          return 0;
+        case VERR_HGCM_INTERNAL:               return -EPROTO;
+        case VERR_HGCM_INVALID_CLIENT_ID:      return -EINVAL;
+        case VINF_HGCM_SAVE_STATE:             return 0;
+        /* No reason to return this to a guest */
+        // case VERR_HGCM_SERVICE_EXISTS:         return -EEXIST;
+        default:
+            AssertMsgFailed(("Unhandled error code %Rrc\n", rc));
+            return -EPROTO;
+    }
+}
+
+
+
+/**
+ * Does the PCI detection and init of the device.
+ *
+ * @returns 0 on success, negated errno on failure.
+ */
+static int __init vboxguestLinuxInitPci(void)
+{
+    struct pci_dev *pPciDev;
+    int             rc;
+
+    pPciDev = PCI_DEV_GET(VMMDEV_VENDORID, VMMDEV_DEVICEID, NULL);
+    if (pPciDev)
+    {
+        rc = pci_enable_device(pPciDev);
+        if (rc >= 0)
+        {
+            /* I/O Ports are mandatory, the MMIO bit is not. */
+            if (pci_resource_start(pPciDev, 0) != 0)
+            {
+                /*
+                 * Map the register address space.
+                 */
+                g_MMIOPhysAddr = pci_resource_start(pPciDev, 1);
+                g_cbMMIO       = pci_resource_len(pPciDev, 1);
+                g_IOPortBase   = pci_resource_start(pPciDev, 0);
+                if (request_mem_region(g_MMIOPhysAddr, g_cbMMIO, DEVICE_NAME) != NULL)
+                {
+                    g_pvMMIOBase = ioremap(g_MMIOPhysAddr, g_cbMMIO);
+                    if (g_DevExt.pVMMDevMemory)
+                    {
+                        /** @todo why aren't we requesting ownership of the I/O ports as well? */
+                        g_pPciDev = pPciDev;
+                        return 0;
+                    }
+
+                    /* failure cleanup path */
+                    LogRel((DEVICE_NAME ": ioremap failed\n"));
+                    rc = -ENOMEM;
+                    release_mem_region(g_MMIOPhysAddr, g_cbMMIO);
+                }
+                else
+                {
+                    LogRel((DEVICE_NAME ": failed to obtain adapter memory\n"));
+                    rc = -EBUSY;
+                }
+                g_MMIOPhysAddr = NIL_RTHCPHYS;
+                g_cbMMIO       = 0;
+                g_IOPortBase   = 0;
+            }
+            else
+            {
+                LogRel((DEVICE_NAME ": did not find expected hardware resources\n"));
+                rc = -ENXIO;
+            }
+            pci_disable_device(pPciDev);
+        }
+        else
+            LogRel((DEVICE_NAME ": could not enable device: %d\n", rc));
+        PCI_DEV_PUT(pPciDev);
+    }
+    else
+    {
+        printk(KERN_ERR DEVICE_NAME ": VirtualBox Guest PCI device not found.\n");
+        rc = -ENODEV;
+    }
+    return rc;
+}
+
+
+/**
+ * Clean up the usage of the PCI device.
+ */
+static void __exit vboxguestLinuxTermPci(void)
+{
+    struct pci_dev *pPciDev = g_pPciDev;
+    g_pPciDev = NULL;
+    if (pPciDev)
+    {
+        iounmap(g_pvMMIOBase);
+        g_pvMMIOBase = NULL;
+
+        release_mem_region(g_MMIOPhysAddr, g_cbMMIO);
+        g_MMIOPhysAddr = NIL_RTHCPHYS;
+        g_cbMMIO = 0;
+
+        pci_disable_device(pPciDev);
+    }
+}
+
+
+/**
+ * Interrupt service routine.
+ *
+ * @returns In 2.4 it returns void.
+ *          In 2.6 we indicate whether we've handled the IRQ or not.
+ *
+ * @param   iIrq            The IRQ number.
+ * @param   pvDevId         The device ID, a pointer to g_DevExt.
+ * @param   pvRegs          Register set. Removed in 2.6.19.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+static irqreturn_t vboxguestLinuxISR(int iIrrq, void *pvDevId)
+#else
+static irqreturn_t vboxguestLinuxISR(int iIrrq, void *pvDevId, struct pt_regs *pRegs)
+#endif
+{
+    bool fTaken = VBoxGuestCommonISR(&g_DevExt);
+    /** @todo  if (vboxDev->irqAckRequest->events &
+     *             VMMDEV_EVENT_MOUSE_POSITION_CHANGED)
+     *             kill_fasync(&vboxDev->async_queue, SIGIO, POLL_IN);
+     */
+    return IRQ_RETVAL(fTaken);
+}
+
+
+/**
+ * Registers the ISR.
+ */
+static int __init vboxguestLinuxInitISR(void)
+{
+    int rc;
+
+    rc = request_irq(g_pPciDev->irq,
+                     vboxguestLinuxISR,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+                     IRQF_SHARED,
+#else
+                     SA_SHIRQ,
+#endif
+                     DEVICE_NAME,
+                     &g_DevExt);
+    if (rc)
+    {
+        LogRel((DEVICE_NAME ": could not request IRQ %d: err=%d\n", g_pPciDev->irq, rc));
+        return rc;
+    }
+    return 0;
+}
+
+
+/**
+ * Deregisters the ISR.
+ */
+static void __exit vboxguestLinuxTermISR(void)
+{
+    free_irq(g_pPciDev->irq, &g_DevExt);
+}
+
+
+/**
+ * Creates the device nodes.
+ *
+ * @returns 0 on success, negated errno on failure.
+ */
+static int __init vboxguestLinuxInitDeviceNodes(void)
+{
+    int rc;
+
+    /*
+     * The full feature device node.
+     */
+    if (g_iModuleMajor > 0)
+    {
+        rc = register_chrdev(g_iModuleMajor, DEVICE_NAME, &g_FileOps);
+        if (rc < 0)
+        {
+            LogRel((DEVICE_NAME ": register_chrdev failed: g_iModuleMajor: %d, rc: %d\n", g_iModuleMajor, rc));
+            return rc;
+        }
+    }
+    else
+    {
+        rc = misc_register(&g_MiscDevice);
+        if (rc)
+        {
+            LogRel((DEVICE_NAME ": misc_register failed for %s (rc=%d)\n", DEVICE_NAME, rc));
+            return rc;
+        }
+    }
+
+    /*
+     * The device node intended to be accessible by all users.
+     */
+    rc = misc_register(&g_MiscDeviceUser);
+    if (rc)
+    {
+        LogRel((DEVICE_NAME ": misc_register failed for %s (rc=%d)\n", DEVICE_NAME_USER, rc));
+        if (g_iModuleMajor > 0)
+            unregister_chrdev(g_iModuleMajor, DEVICE_NAME);
+        else
+            misc_deregister(&g_MiscDevice);
+        return rc;
+    }
+
+    return 0;
+}
+
+
+/**
+ * Deregisters the device nodes.
+ */
+static void __exit vboxguestLinuxTermDeviceNodes(void)
+{
+    if (g_iModuleMajor > 0)
+        unregister_chrdev(g_iModuleMajor, DEVICE_NAME);
+    else
+        misc_deregister(&g_MiscDevice);
+    misc_deregister(&g_MiscDeviceUser);
+}
+
+
+
+/**
+ * Initialize module.
+ *
+ * @returns appropriate status code.
+ */
+static int __init vboxguestLinuxModInit(void)
+{
+    int rc;
+
+    /*
+     * Initialize IPRT first.
+     */
+    rc = RTR0Init(0);
+    if (RT_FAILURE(rc))
+    {
+        Log((DEVICE_NAME ": RTR0Init failed.\n"));
+        return -EINVAL;
+    }
+
+    /*
+     * Locate and initialize the PCI device.
+     */
+    rc = vboxguestLinuxInitPci();
+    if (rc >= 0)
+    {
+        /*
+         * Register the interrupt service routine for it.
+         */
+        rc = vboxguestLinuxInitISR();
+        if (rc >= 0)
+        {
+            /*
+             * Call the common device extension initializer.
+             */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) && defined(RT_ARCH_X86)
+            VBOXOSTYPE enmOSType = VBOXOSTYPE_Linux26;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) && defined(RT_ARCH_AMD64)
+            VBOXOSTYPE enmOSType = VBOXOSTYPE_Linux26_x64;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) && defined(RT_ARCH_X86)
+            VBOXOSTYPE enmOSType = VBOXOSTYPE_Linux24;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) && defined(RT_ARCH_AMD64)
+            VBOXOSTYPE enmOSType = VBOXOSTYPE_Linux24_x64;
+#else
+# warning "huh? which arch + version is this?"
+            VBOXOSTYPE enmOsType = VBOXOSTYPE_Linux;
+#endif
+            rc = VBoxGuestInitDevExt(&g_DevExt,
+                                     g_IOPortBase,
+                                     g_pvMMIOBase,
+                                     g_cbMMIO,
+                                     enmOSType);
+            if (RT_SUCCESS(rc))
+            {
+                /*
+                 * Finally, create the device nodes.
+                 */
+                rc = vboxguestLinuxInitDeviceNodes();
+                if (rc >= 0)
+                {
+                    /* some useful information for the user but don't show this on the console */
+                    LogRel(("VirtualBox device settings: major %d, IRQ %d, I/O port 0x%x, MMIO at 0x%x (size 0x%x)\n",
+                            g_iModuleMajor, g_pPciDev->irq, g_IOPortBase, g_MMIOPhysAddr, g_cbMMIO));
+                    printk(KERN_DEBUG DEVICE_NAME ": Successfully loaded version "
+                            VBOX_VERSION_STRING " (interface " xstr(VMMDEV_VERSION) ")\n");
+                    return rc;
+                }
+
+                /* bail out */
+                VBoxGuestDeleteDevExt(&g_DevExt);
+            }
+            else
+            {
+                LogRel(( DEVICE_NAME ": VBoxGuestInitDevExt failed with rc=%Rrc\n", rc));
+                rc = RTErrConvertFromErrno(rc);
+            }
+            vboxguestLinuxTermISR();
+        }
+        vboxguestLinuxTermPci();
+    }
+    RTR0Term();
+    return rc;
+}
+
+
+/**
+ * Unload the module.
+ */
+static void __exit vboxguestLinuxModExit(void)
+{
+    /*
+     * Inverse order of init.
+     */
+    vboxguestLinuxTermDeviceNodes();
+    VBoxGuestDeleteDevExt(&g_DevExt);
+    vboxguestLinuxTermISR();
+    vboxguestLinuxTermPci();
+    RTR0Term();
+}
+
+
+/**
+ * Device open. Called on open /dev/vboxdrv
+ *
+ * @param   pInode      Pointer to inode info structure.
+ * @param   pFilp       Associated file pointer.
+ */
+static int vboxguestLinuxOpen(struct inode *pInode, struct file *pFilp)
+{
+    int                 rc;
+    PVBOXGUESTSESSION   pSession;
+    Log((DEVICE_NAME ": pFilp=%p pid=%d/%d %s\n", pFilp, RTProcSelf(), current->pid, current->comm));
+
+    /*
+     * Call common code to create the user session. Associate it with
+     * the file so we can access it in the other methods.
+     */
+    rc = VBoxGuestCreateUserSession(&g_DevExt, &pSession);
+    if (RT_SUCCESS(rc))
+        pFilp->private_data = pSession;
+
+    Log(("vboxguestLinuxOpen: g_DevExt=%p pSession=%p rc=%d/%d (pid=%d/%d %s)\n",
+         &g_DevExt, pSession, rc, vboxguestLinuxConvertToNegErrno(rc),
+         RTProcSelf(), current->pid, current->comm));
+    return vboxguestLinuxConvertToNegErrno(rc);
+}
+
+
+/**
+ * Close device.
+ *
+ * @param   pInode      Pointer to inode info structure.
+ * @param   pFilp       Associated file pointer.
+ */
+static int vboxguestLinuxRelease(struct inode *pInode, struct file *pFilp)
+{
+    Log(("vboxguestLinuxRelease: pFilp=%p pSession=%p pid=%d/%d %s\n",
+         pFilp, pFilp->private_data, RTProcSelf(), current->pid, current->comm));
+
+    VBoxGuestCloseSession(&g_DevExt, (PVBOXGUESTSESSION)pFilp->private_data);
+    pFilp->private_data = NULL;
+    return 0;
+}
+
+
+/**
+ * Device I/O Control entry point.
+ *
+ * @param   pFilp       Associated file pointer.
+ * @param   uCmd        The function specified to ioctl().
+ * @param   ulArg       The argument specified to ioctl().
+ */
+#ifdef HAVE_UNLOCKED_IOCTL
+static long vboxguestLinuxIOCtl(struct file *pFilp, unsigned int uCmd, unsigned long ulArg)
+#else
+static int vboxguestLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned int uCmd, unsigned long ulArg)
+#endif
+{
+    PVBOXGUESTSESSION   pSession = (PVBOXGUESTSESSION)pFilp->private_data;
+    uint32_t            cbData   = _IOC_SIZE(uCmd);
+    void               *pvBufFree;
+    void               *pvBuf;
+    int                 rc;
+    uint64_t            au64Buf[32/sizeof(uint64_t)];
+
+    Log6(("vboxguestLinuxIOCtl: pFilp=%p uCmd=%#x ulArg=%p pid=%d/%d\n", pFilp, uCmd, (void *)ulArg, RTProcSelf(), current->pid));
+
+    /*
+     * Buffer the request.
+     */
+    if (cbData <= sizeof(au64Buf))
+    {
+        pvBufFree = NULL;
+        pvBuf = &au64Buf[0];
+    }
+    else
+    {
+        pvBufFree = pvBuf = RTMemTmpAlloc(cbData);
+        if (RT_UNLIKELY(!pvBuf))
+        {
+            LogRel((DEVICE_NAME "::IOCtl: RTMemTmpAlloc failed to alloc %u bytes.\n", cbData));
+            return -ENOMEM;
+        }
+    }
+    if (RT_LIKELY(copy_from_user(pvBuf, (void *)ulArg, cbData)))
+    {
+        /*
+         * Process the IOCtl.
+         */
+        size_t cbDataReturned;
+        rc = VBoxGuestCommonIOCtl(uCmd, &g_DevExt, pSession, pvBuf, cbData, &cbDataReturned);
+
+        /*
+         * Copy ioctl data and output buffer back to user space.
+         */
+        if (RT_LIKELY(!rc))
+        {
+            rc = 0;
+            if (RT_UNLIKELY(cbDataReturned > cbData))
+            {
+                LogRel((DEVICE_NAME "::IOCtl: too much output data %u expected %u\n", cbDataReturned, cbData));
+                cbDataReturned = cbData;
+            }
+            if (cbDataReturned > 0)
+            {
+                if (RT_UNLIKELY(copy_to_user((void *)ulArg, pvBuf, cbDataReturned)))
+                {
+                    LogRel((DEVICE_NAME "::IOCtl: copy_to_user failed; pvBuf=%p ulArg=%p cbDataReturned=%u uCmd=%d\n",
+                            pvBuf, (void *)ulArg, cbDataReturned, uCmd, rc));
+                    rc = -EFAULT;
+                }
+            }
+        }
+        else
+        {
+            Log(("vboxguestLinuxIOCtl: pFilp=%p uCmd=%#x ulArg=%p failed, rc=%d\n", pFilp, uCmd, (void *)ulArg, rc));
+            rc = vboxguestLinuxConvertToNegErrno(rc);
+        }
+    }
+    else
+    {
+        Log((DEVICE_NAME "::IOCtl: copy_from_user(,%#lx, %#x) failed; uCmd=%#x.\n", ulArg, cbData, uCmd));
+        rc = -EFAULT;
+    }
+    if (pvBufFree)
+        RTMemFree(pvBufFree);
+
+    Log6(("vboxguestLinuxIOCtl: returns %d (pid=%d/%d)\n", rc, RTProcSelf(), current->pid));
+    return rc;
+}
+
+/* Common code that depend on g_DevExt. */
+#include "VBoxGuestIDC-unix.c.h"
+
+EXPORT_SYMBOL(VBoxGuestIDCOpen);
+EXPORT_SYMBOL(VBoxGuestIDCClose);
+EXPORT_SYMBOL(VBoxGuestIDCCall);
+
+module_init(vboxguestLinuxModInit);
+module_exit(vboxguestLinuxModExit);
+
+MODULE_AUTHOR("Sun Microsystems, Inc.");
+MODULE_DESCRIPTION("VirtualBox Guest Additions for Linux Module");
+MODULE_LICENSE("GPL");
+#ifdef MODULE_VERSION
+MODULE_VERSION(VBOX_VERSION_STRING " (" xstr(SUPDRV_IOC_VERSION) ")");
+#endif
+
Index: trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c	(revision 21068)
+++ trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c	(revision 21069)
@@ -71,8 +71,4 @@
 static void VBoxGuestSolarisRemoveIRQ(dev_info_t *pDip, void *pvState);
 static uint_t VBoxGuestSolarisISR(caddr_t Arg);
-
-DECLVBGL(int) VBoxGuestSolarisServiceCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned);
-DECLVBGL(void *) VBoxGuestSolarisServiceOpen(uint32_t *pu32Version);
-DECLVBGL(int) VBoxGuestSolarisServiceClose(void *pvSession);
 
 
@@ -195,6 +191,8 @@
 #endif /* USE_SESSION_HASH */
 
+#if 0/** @todo This shouldn't be needed. if it is, that means exceptions hasn't been disabled correctly. */
 /** GCC C++ hack. */
 unsigned __gxx_personality_v0 = 0xdecea5ed;
+#endif
 
 /**
@@ -242,5 +240,5 @@
 static int VBoxGuestSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
 {
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisAttach\n"));
+    LogFlow((DEVICE_NAME "::Attach\n"));
     switch (enmCmd)
     {
@@ -332,5 +330,5 @@
                                      */
                                     rc = VBoxGuestInitDevExt(&g_DevExt, pState->uIOPortBase, pState->pMMIOBase,
-                                                pState->cbMMIO, VBOXOSTYPE_Solaris);
+                                                             pState->cbMMIO, VBOXOSTYPE_Solaris);
                                     if (RT_SUCCESS(rc))
                                     {
@@ -345,32 +343,33 @@
                                         }
 
-                                        LogRel((DEVICE_NAME ":ddi_create_minor_node failed.\n"));
+                                        LogRel((DEVICE_NAME ": ddi_create_minor_node failed.\n"));
+                                        VBoxGuestDeleteDevExt(&g_DevExt);
                                     }
                                     else
-                                        LogRel((DEVICE_NAME ":VBoxGuestInitDevExt failed.\n"));
+                                        LogRel((DEVICE_NAME ": VBoxGuestInitDevExt failed.\n"));
                                     VBoxGuestSolarisRemoveIRQ(pDip, pState);
                                 }
                                 else
-                                    LogRel((DEVICE_NAME ":VBoxGuestSolarisAddIRQ failed.\n"));
+                                    LogRel((DEVICE_NAME ": VBoxGuestSolarisAddIRQ failed.\n"));
                                 ddi_regs_map_free(&pState->PciMMIOHandle);
                             }
                             else
-                                LogRel((DEVICE_NAME ":ddi_regs_map_setup for MMIO region failed.\n"));
+                                LogRel((DEVICE_NAME ": ddi_regs_map_setup for MMIO region failed.\n"));
                         }
                         else
-                            LogRel((DEVICE_NAME ":ddi_dev_regsize for MMIO region failed.\n"));
+                            LogRel((DEVICE_NAME ": ddi_dev_regsize for MMIO region failed.\n"));
                         ddi_regs_map_free(&pState->PciIOHandle);
                     }
                     else
-                        LogRel((DEVICE_NAME ":ddi_regs_map_setup for IOport failed.\n"));
+                        LogRel((DEVICE_NAME ": ddi_regs_map_setup for IOport failed.\n"));
                     pci_config_teardown(&PciHandle);
                 }
                 else
-                    LogRel((DEVICE_NAME ":pci_config_setup failed rc=%d.\n", rc));
+                    LogRel((DEVICE_NAME ": pci_config_setup failed rc=%d.\n", rc));
                 RTSpinlockDestroy(g_Spinlock);
                 g_Spinlock = NIL_RTSPINLOCK;
             }
             else
-                LogRel((DEVICE_NAME ":RTSpinlockCreate failed.\n"));
+                LogRel((DEVICE_NAME ": RTSpinlockCreate failed.\n"));
 
             RTR0Term();
@@ -400,5 +399,5 @@
 static int VBoxGuestSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
 {
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisDetach\n"));
+    LogFlow((DEVICE_NAME "::Detach\n"));
     switch (enmCmd)
     {
@@ -459,5 +458,5 @@
 static int VBoxGuestSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pvArg, void **ppvResult)
 {
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisGetInfo\n"));
+    LogFlow((DEVICE_NAME "::GetInfo\n"));
 
     int rc = DDI_SUCCESS;
@@ -490,5 +489,5 @@
     PVBOXGUESTSESSION   pSession;
 
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisOpen\n"));
+    LogFlow((DEVICE_NAME "::Open\n"));
 
     /*
@@ -512,5 +511,5 @@
     if (!pState)
     {
-        Log((DEVICE_NAME ":VBoxGuestSolarisOpen: too many open instances."));
+        Log((DEVICE_NAME "::Open: too many open instances."));
         return ENXIO;
     }
@@ -524,5 +523,5 @@
         pState->pSession = pSession;
         *pDev = makedevice(getmajor(*pDev), iOpenInstance);
-        Log((DEVICE_NAME "VBoxGuestSolarisOpen: pSession=%p pState=%p pid=%d\n", pSession, pState, (int)RTProcSelf()));
+        Log((DEVICE_NAME "::Open: pSession=%p pState=%p pid=%d\n", pSession, pState, (int)RTProcSelf()));
         return 0;
     }
@@ -556,13 +555,13 @@
         if (instance >= 4096)
         {
-            Log((DEVICE_NAME ":VBoxGuestSolarisOpen: All instances exhausted\n"));
+            Log((DEVICE_NAME "::Open: All instances exhausted\n"));
             return ENXIO;
         }
         *pDev = makedevice(getmajor(*pDev), instance);
-        Log((DEVICE_NAME ":VBoxGuestSolarisOpen success: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf()));
+        Log((DEVICE_NAME "::Open success: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf()));
         return 0;
     }
 #endif
-    LogRel((DEVICE_NAME ":VBoxGuestSolarisOpen: VBoxGuestCreateUserSession failed. rc=%d\n", rc));
+    LogRel((DEVICE_NAME "::Open: VBoxGuestCreateUserSession failed. rc=%d\n", rc));
     return EFAULT;
 }
@@ -571,5 +570,5 @@
 static int VBoxGuestSolarisClose(dev_t Dev, int flag, int fType, cred_t *pCred)
 {
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisClose pid=%d\n", (int)RTProcSelf()));
+    LogFlow((DEVICE_NAME "::Close pid=%d\n", (int)RTProcSelf()));
 
 #ifndef USE_SESSION_HASH
@@ -578,5 +577,5 @@
     if (!pState)
     {
-        Log((DEVICE_NAME ":VBoxGuestSolarisClose: failed to get pState.\n"));
+        Log((DEVICE_NAME "::Close: failed to get pState.\n"));
         return EFAULT;
     }
@@ -584,9 +583,9 @@
     pSession = pState->pSession;
     pState->pSession = NULL;
-    Log((DEVICE_NAME ":VBoxGuestSolarisClose: pSession=%p pState=%p\n", pSession, pState));
+    Log((DEVICE_NAME "::Close: pSession=%p pState=%p\n", pSession, pState));
     ddi_soft_state_free(g_pVBoxGuestSolarisState, getminor(Dev));
     if (!pSession)
     {
-        Log((DEVICE_NAME ":VBoxGuestSolarisClose: failed to get pSession.\n"));
+        Log((DEVICE_NAME "::Close: failed to get pSession.\n"));
         return EFAULT;
     }
@@ -632,8 +631,8 @@
     if (!pSession)
     {
-        Log((DEVICE_NAME ":VBoxGuestSolarisClose: WHUT?!? pSession == NULL! This must be a mistake... pid=%d", (int)Process));
+        Log((DEVICE_NAME "::Close: WHUT?!? pSession == NULL! This must be a mistake... pid=%d", (int)Process));
         return EFAULT;
     }
-    Log((DEVICE_NAME ":VBoxGuestSolarisClose: pid=%d\n", (int)Process));
+    Log((DEVICE_NAME "::Close: pid=%d\n", (int)Process));
 #endif /* USE_SESSION_HASH */
 
@@ -648,5 +647,5 @@
 static int VBoxGuestSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred)
 {
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisRead\n"));
+    LogFlow((DEVICE_NAME "::Read\n"));
     return 0;
 }
@@ -655,5 +654,5 @@
 static int VBoxGuestSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred)
 {
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisWrite\n"));
+    LogFlow((DEVICE_NAME "::Write\n"));
     return 0;
 }
@@ -692,5 +691,5 @@
     if (!pState)
     {
-        Log((DEVICE_NAME ":VBoxGuestSolarisIOCtl: no state data for %d\n", getminor(Dev)));
+        Log((DEVICE_NAME "::IOCtl: no state data for %d\n", getminor(Dev)));
         return EINVAL;
     }
@@ -699,5 +698,5 @@
     if (!pSession)
     {
-        Log((DEVICE_NAME ":VBoxGuestSolarisIOCtl: no session data for %d\n", getminor(Dev)));
+        Log((DEVICE_NAME "::IOCtl: no session data for %d\n", getminor(Dev)));
         return EINVAL;
     }
@@ -722,5 +721,5 @@
     if (!pSession)
     {
-        Log((DEVICE_NAME ":VBoxGuestSolarisIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x\n", (int)Process, Cmd));
+        Log((DEVICE_NAME "::IOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x\n", (int)Process, Cmd));
         return EINVAL;
     }
@@ -733,5 +732,5 @@
     if (IOCPARM_LEN(Cmd) != sizeof(ReqWrap))
     {
-        LogRel((DEVICE_NAME ": VBoxGuestSolarisIOCtl: bad request %#x size=%d expected=%d\n", Cmd, IOCPARM_LEN(Cmd), sizeof(ReqWrap)));
+        LogRel((DEVICE_NAME "::IOCtl: bad request %#x size=%d expected=%d\n", Cmd, IOCPARM_LEN(Cmd), sizeof(ReqWrap)));
         return ENOTTY;
     }
@@ -740,5 +739,5 @@
     if (RT_UNLIKELY(rc))
     {
-        LogRel((DEVICE_NAME ": VBoxGuestSolarisIOCtl: ddi_copyin failed to read header pArg=%p Cmd=%d. rc=%d.\n", pArg, Cmd, rc));
+        LogRel((DEVICE_NAME "::IOCtl: ddi_copyin failed to read header pArg=%p Cmd=%d. rc=%d.\n", pArg, Cmd, rc));
         return EINVAL;
     }
@@ -746,5 +745,5 @@
     if (ReqWrap.u32Magic != VBGLBIGREQ_MAGIC)
     {
-        LogRel((DEVICE_NAME ": VBoxGuestSolarisIOCtl: bad magic %#x; pArg=%p Cmd=%d.\n", ReqWrap.u32Magic, pArg, Cmd));
+        LogRel((DEVICE_NAME "::IOCtl: bad magic %#x; pArg=%p Cmd=%d.\n", ReqWrap.u32Magic, pArg, Cmd));
         return EINVAL;
     }
@@ -752,5 +751,5 @@
                     || ReqWrap.cbData > _1M*16))
     {
-        Log((DEVICE_NAME ": VBoxGuestSolarisIOCtl: bad size %#x; pArg=%p Cmd=%d.\n", ReqWrap.cbData, pArg, Cmd));
+        Log((DEVICE_NAME "::IOCtl: bad size %#x; pArg=%p Cmd=%d.\n", ReqWrap.cbData, pArg, Cmd));
         return EINVAL;
     }
@@ -762,5 +761,5 @@
     if (RT_UNLIKELY(!pvBuf))
     {
-        LogRel((DEVICE_NAME ":VBoxGuestSolarisIOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap.cbData));
+        LogRel((DEVICE_NAME "::IOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap.cbData));
         return ENOMEM;
     }
@@ -770,5 +769,5 @@
     {
         RTMemTmpFree(pvBuf);
-        LogRel((DEVICE_NAME ":VBoxGuestSolarisIOCtl: ddi_copyin failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
+        LogRel((DEVICE_NAME "::IOCtl: ddi_copyin failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
         return EFAULT;
     }
@@ -777,8 +776,8 @@
     {
         RTMemTmpFree(pvBuf);
-        LogRel((DEVICE_NAME ":VBoxGuestSolarisIOCtl: pvBuf invalid pointer %p\n", pvBuf));
+        LogRel((DEVICE_NAME "::IOCtl: pvBuf invalid pointer %p\n", pvBuf));
         return EINVAL;
     }
-    Log((DEVICE_NAME ":VBoxGuestSolarisIOCtl: pSession=%p pid=%d.\n", pSession, (int)RTProcSelf()));
+    Log((DEVICE_NAME "::IOCtl: pSession=%p pid=%d.\n", pSession, (int)RTProcSelf()));
 
     /*
@@ -792,5 +791,5 @@
         if (RT_UNLIKELY(cbDataReturned > ReqWrap.cbData))
         {
-            LogRel((DEVICE_NAME ":VBoxGuestSolarisIOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap.cbData));
+            LogRel((DEVICE_NAME "::IOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap.cbData));
             cbDataReturned = ReqWrap.cbData;
         }
@@ -800,5 +799,6 @@
             if (RT_UNLIKELY(rc))
             {
-                LogRel((DEVICE_NAME ":VBoxGuestSolarisIOCtl: ddi_copyout failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
+                LogRel((DEVICE_NAME "::IOCtl: ddi_copyout failed; pvBuf=%p pArg=%p cbDataReturned=%u Cmd=%d. rc=%d\n",
+                        pvBuf, pArg, cbDataReturned, Cmd, rc));
                 rc = EFAULT;
             }
@@ -807,5 +807,5 @@
     else
     {
-        LogRel((DEVICE_NAME ":VBoxGuestSolarisIOCtl: VBoxGuestCommonIOCtl failed. rc=%d\n", rc));
+        LogRel((DEVICE_NAME "::IOCtl: VBoxGuestCommonIOCtl failed. rc=%d\n", rc));
         rc = RTErrConvertToErrno(rc);
     }
@@ -825,5 +825,5 @@
 static int VBoxGuestSolarisAddIRQ(dev_info_t *pDip, void *pvState)
 {
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisAddIRQ %p\n", pvState));
+    LogFlow((DEVICE_NAME "::AddIRQ: %p\n", pvState));
 
     vboxguest_state_t *pState = (vboxguest_state_t *)pvState;
@@ -903,5 +903,5 @@
                             }
                             else
-                                LogRel((DEVICE_NAME ":VBoxGuestSolarisAddIRQ: failed to get priority of interrupt. rc=%d\n", rc));
+                                LogRel((DEVICE_NAME "::AddIRQ: failed to get priority of interrupt. rc=%d\n", rc));
 
                             /* Remove allocated IRQs, too bad we can free only one handle at a time. */
@@ -910,21 +910,21 @@
                         }
                         else
-                            LogRel((DEVICE_NAME ":VBoxGuestSolarisAddIRQ: failed to allocated IRQs. count=%d\n", IntrCount));
+                            LogRel((DEVICE_NAME "::AddIRQ: failed to allocated IRQs. count=%d\n", IntrCount));
                         RTMemFree(pState->pIntr);
                     }
                     else
-                        LogRel((DEVICE_NAME ":VBoxGuestSolarisAddIRQ: failed to allocated IRQs. count=%d\n", IntrCount));
+                        LogRel((DEVICE_NAME "::AddIRQ: failed to allocated IRQs. count=%d\n", IntrCount));
                 }
                 else
-                    LogRel((DEVICE_NAME ":VBoxGuestSolarisAddIRQ: failed to get or insufficient available IRQs. rc=%d IntrAvail=%d\n", rc, IntrAvail));
+                    LogRel((DEVICE_NAME "::AddIRQ: failed to get or insufficient available IRQs. rc=%d IntrAvail=%d\n", rc, IntrAvail));
             }
             else
-                LogRel((DEVICE_NAME ":VBoxGuestSolarisAddIRQ: failed to get or insufficient number of IRQs. rc=%d IntrCount=%d\n", rc, IntrCount));
+                LogRel((DEVICE_NAME "::AddIRQ: failed to get or insufficient number of IRQs. rc=%d IntrCount=%d\n", rc, IntrCount));
         }
         else
-            LogRel((DEVICE_NAME ":VBoxGuestSolarisAddIRQ: invalid irq type. IntrType=%#x\n", IntrType));
+            LogRel((DEVICE_NAME "::AddIRQ: invalid irq type. IntrType=%#x\n", IntrType));
     }
     else
-        LogRel((DEVICE_NAME ":VBoxGuestSolarisAddIRQ: failed to get supported interrupt types\n"));
+        LogRel((DEVICE_NAME "::AddIRQ: failed to get supported interrupt types\n"));
     return rc;
 #endif
@@ -941,5 +941,5 @@
 {
     vboxguest_state_t *pState = (vboxguest_state_t *)pvState;
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisRemoveIRQ pvState=%p\n"));
+    LogFlow((DEVICE_NAME "::RemoveIRQ: pvState=%p\n"));
 
 #if 0
@@ -970,5 +970,5 @@
 static uint_t VBoxGuestSolarisISR(caddr_t Arg)
 {
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisISR Arg=%p\n", Arg));
+    LogFlow((DEVICE_NAME "::ISR: Arg=%p\n", Arg));
 
     vboxguest_state_t *pState = (vboxguest_state_t *)Arg;
@@ -981,69 +981,5 @@
 
 
-/**
- * VBoxGuest Common ioctl wrapper from VBoxGuestLib.
- *
- * @returns VBox error code.
- * @param   pvSession           Opaque pointer to the session.
- * @param   iCmd                Requested function.
- * @param   pvData              IO data buffer.
- * @param   cbData              Size of the data buffer.
- * @param   pcbDataReturned     Where to store the amount of returned data.
- */
-DECLVBGL(int) VBoxGuestSolarisServiceCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned)
-{
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisServiceCall %pvSesssion=%p Cmd=%u pvData=%p cbData=%d\n", pvSession, iCmd, pvData, cbData));
-
-    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
-    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
-    AssertMsgReturn(pSession->pDevExt == &g_DevExt,
-                    ("SC: %p != %p\n", pSession->pDevExt, &g_DevExt), VERR_INVALID_HANDLE);
-
-    return VBoxGuestCommonIOCtl(iCmd, &g_DevExt, pSession, pvData, cbData, pcbDataReturned);
-}
-
-
-/**
- * Solaris Guest service open.
- *
- * @returns Opaque pointer to session object.
- * @param   pu32Version         Where to store VMMDev version.
- */
-DECLVBGL(void *) VBoxGuestSolarisServiceOpen(uint32_t *pu32Version)
-{
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisServiceOpen\n"));
-
-    AssertPtrReturn(pu32Version, NULL);
-    PVBOXGUESTSESSION pSession;
-    int rc = VBoxGuestCreateKernelSession(&g_DevExt, &pSession);
-    if (RT_SUCCESS(rc))
-    {
-        *pu32Version = VMMDEV_VERSION;
-        return pSession;
-    }
-    LogRel((DEVICE_NAME ":VBoxGuestCreateKernelSession failed. rc=%d\n", rc));
-    return NULL;
-}
-
-
-/**
- * Solaris Guest service close.
- *
- * @returns VBox error code.
- * @param   pvState             Opaque pointer to the session object.
- */
-DECLVBGL(int) VBoxGuestSolarisServiceClose(void *pvSession)
-{
-    LogFlow((DEVICE_NAME ":VBoxGuestSolarisServiceClose\n"));
-
-    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
-    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
-    if (pSession)
-    {
-        VBoxGuestCloseSession(&g_DevExt, pSession);
-        return VINF_SUCCESS;
-    }
-    LogRel((DEVICE_NAME ":Invalid pSession.\n"));
-    return VERR_INVALID_HANDLE;
-}
-
+/* Common code that depend on g_DevExt. */
+#include "VBoxGuestIDC-unix.c.h"
+
Index: trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp	(revision 21068)
+++ trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp	(revision 21069)
@@ -1451,2 +1451,3 @@
 }
 
+
Index: trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h	(revision 21069)
+++ trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h	(revision 21069)
@@ -0,0 +1,99 @@
+/* $Rev$ */
+/** @file
+ * VBoxGuest - Inter Driver Communcation, unix implementation.
+ *
+ * This file is included by the platform specific source file.
+ */
+
+/*
+ * Copyright (C) 2006-2009 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ * Some lines of code to disable the local APIC on x86_64 machines taken
+ * from a Mandriva patch by Gwenole Beauchesne <gbeauchesne@mandriva.com>.
+ */
+
+
+/**
+ * Open a new IDC connection.
+ *
+ * @returns Opaque pointer to session object.
+ * @param   pu32Version         Where to store VMMDev version.
+ */
+DECLVBGL(void *) VBoxGuestIDCOpen(uint32_t *pu32Version)
+{
+    PVBOXGUESTSESSION   pSession;
+    int                 rc;
+    LogFlow(("VBoxGuestIDCOpen: Version=%#x\n", pu32Version ? *pu32Version : 0));
+
+    AssertPtrReturn(pu32Version, NULL);
+    rc = VBoxGuestCreateKernelSession(&g_DevExt, &pSession);
+    if (RT_SUCCESS(rc))
+    {
+        *pu32Version = VMMDEV_VERSION;
+        return pSession;
+    }
+    LogRel(("VBoxGuestIDCOpen: VBoxGuestCreateKernelSession failed. rc=%d\n", rc));
+    return NULL;
+}
+
+
+/**
+ * Close an IDC connection.
+ *
+ * @returns VBox error code.
+ * @param   pvState             Opaque pointer to the session object.
+ */
+DECLVBGL(int) VBoxGuestIDCClose(void *pvSession)
+{
+    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
+    LogFlow(("VBoxGuestIDCClose:\n"));
+
+    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
+    VBoxGuestCloseSession(&g_DevExt, pSession);
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Perform an IDC call.
+ *
+ * @returns VBox error code.
+ * @param   pvSession           Opaque pointer to the session.
+ * @param   iCmd                Requested function.
+ * @param   pvData              IO data buffer.
+ * @param   cbData              Size of the data buffer.
+ * @param   pcbDataReturned     Where to store the amount of returned data.
+ */
+DECLVBGL(int) VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned)
+{
+    PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
+    LogFlow(("VBoxGuestIDCCall: %pvSesssion=%p Cmd=%u pvData=%p cbData=%d\n", pvSession, iCmd, pvData, cbData));
+
+    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
+    AssertMsgReturn(pSession->pDevExt == &g_DevExt,
+                    ("SC: %p != %p\n", pSession->pDevExt, &g_DevExt), VERR_INVALID_HANDLE);
+
+    return VBoxGuestCommonIOCtl(iCmd, &g_DevExt, pSession, pvData, cbData, pcbDataReturned);
+}
+
+
Index: trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h	(revision 21068)
+++ trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h	(revision 21069)
@@ -162,4 +162,12 @@
                           void *pvData, size_t cbData, size_t *pcbDataReturned);
 
+#if defined(RT_OS_SOLARIS) \
+ || defined(RT_OS_FREEBSD) \
+ || defined(RT_OS_LINUX)
+DECLVBGL(void *) VBoxGuestNativeServiceOpen(uint32_t *pu32Version);
+DECLVBGL(void)   VBoxGuestNativeServiceClose(void *pvOpaque);
+DECLVBGL(int)    VBoxGuestNativeServiceCall(void *pvOpaque, unsigned int iCmd, void *pvData, size_t cbSize, size_t *pcbReturn);
+#endif
+
 RT_C_DECLS_END
 
Index: trunk/src/VBox/Additions/common/VBoxGuestLib/SysHlp.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuestLib/SysHlp.cpp	(revision 21068)
+++ trunk/src/VBox/Additions/common/VBoxGuestLib/SysHlp.cpp	(revision 21069)
@@ -1,10 +1,9 @@
+/* $Revision$ */
 /** @file
- *
- * VBoxGuestLib - A support library for VirtualBox guest additions:
- * Physical memory heap
+ * VBoxGuestLib - IDC with VBoxGuest and HGCM helpers.
  */
 
 /*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2009 Sun Microsystems, Inc.
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -20,4 +19,5 @@
  * additional information or have any questions.
  */
+
 #define LOG_GROUP LOG_GROUP_HGCM
 #include <VBox/log.h>
@@ -27,6 +27,7 @@
 
 #include <iprt/assert.h>
-#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_LINUX)
-#include <iprt/memobj.h>
+#if !defined (RT_OS_WINDOWS) \
+ && (!defined (RT_OS_LINUX) || defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX))
+# include <iprt/memobj.h>
 #endif
 
@@ -74,8 +75,5 @@
     }
 
-#elif defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
-    /** @todo r=bird: I don't think FreeBSD shouldn't go here, solaris and OS/2 doesn't
-      * That said, the assumption below might be wrong for in kernel calls... */
-
+#elif defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
     /** @todo r=frank: Linux: pv is at least in some cases, e.g. with VBoxMapFolder,
      *  an R0 address -- the memory was allocated with kmalloc(). I don't know
@@ -120,5 +118,5 @@
     }
 
-#elif defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
+#elif defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
     NOREF(pvCtx);
 
@@ -134,12 +132,12 @@
 #ifndef VBGL_VBOXGUEST
 
-#if defined (RT_OS_LINUX) && !defined (__KERNEL__)
-# include <unistd.h>
-# include <errno.h>
-# include <sys/fcntl.h>
-# include <sys/ioctl.h>
-#endif
-
-#ifdef RT_OS_LINUX
+# if defined (RT_OS_LINUX) && !defined (__KERNEL__) /** @todo r=bird: What is this for?????? */
+#  include <unistd.h>
+#  include <errno.h>
+#  include <sys/fcntl.h>
+#  include <sys/ioctl.h>
+# endif
+
+# if defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
 RT_C_DECLS_BEGIN
 extern DECLVBGL(void *) vboxadd_cmc_open (void);
@@ -147,7 +145,7 @@
 extern DECLVBGL(int) vboxadd_cmc_call (void *opaque, uint32_t func, void *data);
 RT_C_DECLS_END
-#endif /* RT_OS_LINUX */
-
-#ifdef RT_OS_OS2
+# endif /* RT_OS_LINUX */
+
+# ifdef RT_OS_OS2
 RT_C_DECLS_BEGIN
 /*
@@ -158,25 +156,19 @@
 extern VBOXGUESTOS2IDCCONNECT g_VBoxGuestIDC;
 RT_C_DECLS_END
-#endif
-
-#ifdef RT_OS_SOLARIS
+# endif
+
+# if !defined(RT_OS_OS2) \
+  && !defined(RT_OS_WINDOWS) \
+  && (!defined (RT_OS_LINUX) || defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX))
 RT_C_DECLS_BEGIN
-extern DECLVBGL(void *) VBoxGuestSolarisServiceOpen (uint32_t *pu32Version);
-extern DECLVBGL(void) VBoxGuestSolarisServiceClose (void *pvOpaque);
-extern DECLVBGL(int) VBoxGuestSolarisServiceCall (void *pvOpaque, unsigned int iCmd, void *pvData, size_t cbSize, size_t *pcbReturn);
+extern DECLVBGL(void *) VBoxGuestIDCOpen (uint32_t *pu32Version);
+extern DECLVBGL(void)   VBoxGuestIDCClose (void *pvOpaque);
+extern DECLVBGL(int)    VBoxGuestIDCCall (void *pvOpaque, unsigned int iCmd, void *pvData, size_t cbSize, size_t *pcbReturn);
 RT_C_DECLS_END
-
-#elif defined (RT_OS_FREEBSD)
-RT_C_DECLS_BEGIN
-extern DECLVBGL(void *) VBoxGuestFreeBSDServiceOpen (uint32_t *pu32Version);
-extern DECLVBGL(void) VBoxGuestFreeBSDServiceClose (void *pvOpaque);
-extern DECLVBGL(int) VBoxGuestFreeBSDServiceCall (void *pvOpaque, unsigned int iCmd, void *pvData, size_t cbSize, size_t *pcbReturn);
-RT_C_DECLS_END
-
-#endif
+# endif
 
 int vbglDriverOpen (VBGLDRIVER *pDriver)
 {
-#ifdef RT_OS_WINDOWS
+# ifdef RT_OS_WINDOWS
     UNICODE_STRING uszDeviceName;
     RtlInitUnicodeString (&uszDeviceName, L"\\Device\\VBoxGuest");
@@ -199,5 +191,6 @@
     return rc;
 
-#elif defined (RT_OS_LINUX)
+# elif defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
+
     void *opaque;
 
@@ -210,5 +203,5 @@
     return VINF_SUCCESS;
 
-#elif defined (RT_OS_OS2)
+# elif defined (RT_OS_OS2)
     /*
      * Just check whether the connection was made or not.
@@ -225,7 +218,7 @@
     return VERR_FILE_NOT_FOUND;
 
-#elif defined (RT_OS_SOLARIS)
+# else
     uint32_t u32VMMDevVersion;
-    pDriver->pvOpaque = VBoxGuestSolarisServiceOpen(&u32VMMDevVersion);
+    pDriver->pvOpaque = VBoxGuestIDCOpen (&u32VMMDevVersion);
     if (    pDriver->pvOpaque
         &&  u32VMMDevVersion == VMMDEV_VERSION)
@@ -234,20 +227,8 @@
     Log(("vbglDriverOpen: failed\n"));
     return VERR_FILE_NOT_FOUND;
-
-#elif defined (RT_OS_FREEBSD)
-    uint32_t u32VMMDevVersion;
-    pDriver->pvOpaque = VBoxGuestFreeBSDServiceOpen(&u32VMMDevVersion);
-    if (pDriver->pvOpaque && (u32VMMDevVersion == VMMDEV_VERSION))
-        return VINF_SUCCESS;
-
-    Log(("vbglDriverOpen: failed\n"));
-    return VERR_FILE_NOT_FOUND;
-
-#else
-# error "Port me"
-#endif
-}
-
-#ifdef RT_OS_WINDOWS
+# endif
+}
+
+# ifdef RT_OS_WINDOWS
 static NTSTATUS vbglDriverIOCtlCompletion (IN PDEVICE_OBJECT DeviceObject,
                                            IN PIRP Irp,
@@ -261,5 +242,5 @@
     return STATUS_MORE_PROCESSING_REQUIRED;
 }
-#endif
+# endif
 
 int vbglDriverIOCtl (VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData)
@@ -267,5 +248,5 @@
     Log(("vbglDriverIOCtl: pDriver: %p, Func: %x, pvData: %p, cbData: %d\n", pDriver, u32Function, pvData, cbData));
 
-#ifdef RT_OS_WINDOWS
+# ifdef RT_OS_WINDOWS
     KEVENT Event;
 
@@ -330,8 +311,8 @@
     return NT_SUCCESS(rc)? VINF_SUCCESS: VERR_VBGL_IOCTL_FAILED;
 
-#elif defined (RT_OS_LINUX)
+# elif defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
     return vboxadd_cmc_call (pDriver->opaque, u32Function, pvData);
 
-#elif defined (RT_OS_OS2)
+# elif defined (RT_OS_OS2)
     if (    pDriver->u32Session
         &&  pDriver->u32Session == g_VBoxGuestIDC.u32Session)
@@ -341,36 +322,24 @@
     return VERR_WRONG_ORDER;
 
-#elif defined (RT_OS_SOLARIS)
-    return VBoxGuestSolarisServiceCall(pDriver->pvOpaque, u32Function, pvData, cbData, NULL);
-
-#elif defined (RT_OS_FREEBSD)
-    return VBoxGuestFreeBSDServiceCall(pDriver->pvOpaque, u32Function, pvData, cbData, NULL);
-
-#else
-# error "Port me"
-#endif
+# else
+    return VBoxGuestIDCCall(pDriver->pvOpaque, u32Function, pvData, cbData, NULL);
+# endif
 }
 
 void vbglDriverClose (VBGLDRIVER *pDriver)
 {
-#ifdef RT_OS_WINDOWS
+# ifdef RT_OS_WINDOWS
     Log(("vbglDriverClose pDeviceObject=%x\n", pDriver->pDeviceObject));
     ObDereferenceObject (pDriver->pFileObject);
 
-#elif defined (RT_OS_LINUX)
+# elif defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
     vboxadd_cmc_close (pDriver->opaque);
 
-#elif defined (RT_OS_OS2)
+# elif defined (RT_OS_OS2)
     pDriver->u32Session = 0;
 
-#elif defined (RT_OS_SOLARIS)
-    VBoxGuestSolarisServiceClose (pDriver->pvOpaque);
-
-#elif defined (RT_OS_FREEBSD)
-    VBoxGuestFreeBSDServiceClose(pDriver->pvOpaque);
-
-#else
-# error "Port me"
-#endif
+# else
+    VBoxGuestIDCClose (pDriver->pvOpaque);
+# endif
 }
 
