VirtualBox

Changeset 45459 in vbox for trunk/src/VBox/Additions/common


Ignore:
Timestamp:
Apr 10, 2013 3:24:23 PM (12 years ago)
Author:
vboxsync
Message:

BUGZ:4686 OS X guest: VBoxGuest device driver + VBoxService and VBoxControl now work.

Location:
trunk/src/VBox/Additions/common
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/Makefile.kmk

    r43363 r45459  
    2323 include $(PATH_SUB_CURRENT)/VBoxGuestLib/Makefile.kmk
    2424 include $(PATH_SUB_CURRENT)/VBoxControl/Makefile.kmk
    25  if1of ($(KBUILD_TARGET), freebsd haiku linux os2 solaris win)
    26   include $(PATH_SUB_CURRENT)/VBoxGuest/Makefile.kmk
    27  endif
    28  if1of ($(KBUILD_TARGET), freebsd haiku linux os2 solaris win)
    29   include $(PATH_SUB_CURRENT)/VBoxService/Makefile.kmk
    30  endif
     25 include $(PATH_SUB_CURRENT)/VBoxGuest/Makefile.kmk
     26 include $(PATH_SUB_CURRENT)/VBoxService/Makefile.kmk
    3127 ifdef VBOX_WITH_CROGL
    3228   include $(PATH_SUB_CURRENT)/crOpenGL/Makefile.kmk
  • trunk/src/VBox/Additions/common/VBoxControl/Makefile.kmk

    r42239 r45459  
    4343VBoxControl_SOURCES.win = \
    4444        VBoxControl.rc
     45VBoxControl_LDFLAGS.darwin = -framework IOKit
    4546
    4647include $(FILE_KBUILD_SUB_FOOTER)
  • trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk

    r43363 r45459  
    2020
    2121
    22 if1of ($(KBUILD_TARGET), freebsd haiku $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linux,) os2 solaris win)
     22if1of ($(KBUILD_TARGET), darwin freebsd haiku $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linux,) os2 solaris win)
    2323 #
    2424 # VBoxGuest - The Guest Additions Driver.
     
    3030 VBoxGuest_NAME.linux    = vboxguest
    3131 VBoxGuest_NAME.solaris  = vboxguest
     32 VBoxGuest_INST.darwin   = $(INST_ADDITIONS)VBoxGuest.kext/Contents/MacOS/
    3233 ifdef VBOX_SIGN_ADDITIONS # See Additions/WINNT/Makefile.kmk?
    3334  VBoxGuest_INSTTYPE.win = none
     
    5152 VBoxGuest_DEPS.solaris += $(VBOX_SVN_REV_KMK)
    5253 VBoxGuest_DEPS.linux   += $(VBOX_SVN_REV_HEADER)
     54 VBoxGuest_DEPS.haiku   += $(VBOX_SVN_REV_HEADER)
    5355 VBoxGuest_DEPS.freebsd += $(VBOX_SVN_REV_HEADER)
    54  VBoxGuest_DEPS.haiku   += $(VBOX_SVN_REV_HEADER)
     56 VBoxGuest_DEPS.darwin  += $(VBOX_SVN_REV_HEADER)
    5557 VBoxGuest_DEFS          = VBGL_VBOXGUEST VBOX_WITH_HGCM
    5658 VBoxGuest_INCS          = .
     
    165167endif # enabled
    166168
     169
     170ifeq ($(KBUILD_TARGET), darwin)
     171 # Files necessary to make a darwin kernel extension bundle.
     172 INSTALLS += VBoxGuest.kext
     173 VBoxGuest.kext_INST     = $(INST_ADDITIONS)/VBoxGuest.kext/Contents/
     174 VBoxGuest.kext_SOURCES  = $(VBoxGuest.kext_0_OUTDIR)/Info.plist
     175 VBoxGuest.kext_CLEAN    = $(VBoxGuest.kext_0_OUTDIR)/Info.plist
     176
     177$$(VBoxGuest.kext_0_OUTDIR)/Info.plist: \
     178                $(PATH_SUB_CURRENT)/darwin/Info.plist \
     179                $(VBOX_VERSION_MK) | $$(dir $$@)
     180        $(call MSG_GENERATE,VBoxGuest,$@,$<)
     181        $(QUIET)$(RM) -f $@
     182        $(QUIET)$(SED) \
     183                -e 's/@VBOX_VERSION_STRING@/$(VBOX_VERSION_STRING)/g' \
     184                -e 's/@VBOX_VERSION_MAJOR@/$(VBOX_VERSION_MAJOR)/g' \
     185                -e 's/@VBOX_VERSION_MINOR@/$(VBOX_VERSION_MINOR)/g' \
     186                -e 's/@VBOX_VERSION_BUILD@/$(VBOX_VERSION_BUILD)/g' \
     187                -e 's/@VBOX_VENDOR@/$(VBOX_VENDOR)/g' \
     188                -e 's/@VBOX_PRODUCT@/$(VBOX_PRODUCT)/g' \
     189                -e 's/@VBOX_C_YEAR@/$(VBOX_C_YEAR)/g' \
     190                --output $@ \
     191                $<
     192endif # darwin
     193
     194
    167195ifeq ($(KBUILD_TARGET),linux)
    168196 #
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-darwin.cpp

    r45447 r45459  
    11/* $Id$ */
    22/** @file
    3  * VirtualBox Support Driver - Darwin Specific Code.
     3 * VBoxGuest - Darwin Specifics.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2006-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2828*   Header Files                                                               *
    2929*******************************************************************************/
    30 #define LOG_GROUP LOG_GROUP_SUP_DRV
     30#define LOG_GROUP LOG_GROUP_VBGD
    3131/*
    3232 * Deal with conflicts first.
     
    4040#include <IOKit/IOLib.h> /* Assert as function */
    4141
    42 #include "../SUPDrvInternal.h"
    4342#include <VBox/version.h>
    4443#include <iprt/asm.h>
    45 #include <iprt/asm-amd64-x86.h>
    4644#include <iprt/initterm.h>
    4745#include <iprt/assert.h>
     
    5149#include <iprt/alloc.h>
    5250#include <iprt/power.h>
    53 #include <iprt/dbg.h>
    5451#include <VBox/err.h>
    5552#include <VBox/log.h>
     
    6663#include <IOKit/IOUserClient.h>
    6764#include <IOKit/pwr_mgt/RootDomain.h>
    68 #include <IOKit/IODeviceTreeSupport.h>
    69 
    70 #ifdef VBOX_WITH_HOST_VMX
    71 # include <libkern/version.h>
    72 RT_C_DECLS_BEGIN
    73 # include <i386/vmx.h>
    74 RT_C_DECLS_END
    75 #endif
     65#include <IOkit/pci/IOPCIDevice.h>
     66#include <IOkit/IOBufferMemoryDescriptor.h>
     67#include <IOkit/IOFilterInterruptEventSource.h>
     68#include "VBoxGuestInternal.h"
    7669
    7770
     
    8174
    8275/** The system device node name. */
    83 #define DEVICE_NAME_SYS     "vboxdrv"
     76#define DEVICE_NAME_SYS     "vboxguest"
    8477/** The user device node name. */
    85 #define DEVICE_NAME_USR     "vboxdrvu"
     78#define DEVICE_NAME_USR     "vboxguestu"
    8679
    8780
     
    9184*******************************************************************************/
    9285RT_C_DECLS_BEGIN
    93 static kern_return_t    VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pvData);
    94 static kern_return_t    VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvData);
    95 
    96 static int              VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
    97 static int              VBoxDrvDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
    98 static int              VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess);
    99 static int              VBoxDrvDarwinIOCtlSlow(PSUPDRVSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess);
    100 
    101 static int              VBoxDrvDarwinErr2DarwinErr(int rc);
    102 
    103 static IOReturn         VBoxDrvDarwinSleepHandler(void *pvTarget, void *pvRefCon, UInt32 uMessageType, IOService *pProvider, void *pvMessageArgument, vm_size_t argSize);
     86static kern_return_t    VbgdDarwinStart(struct kmod_info *pKModInfo, void *pvData);
     87static kern_return_t    VbgdDarwinStop(struct kmod_info *pKModInfo, void *pvData);
     88static int              VbgdDarwinCharDevRemove(void);
     89
     90static int              VbgdDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
     91static int              VbgdDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
     92static int              VbgdDarwinIOCtlSlow(PVBOXGUESTSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess);
     93static int              VbgdDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess);
     94
     95static int              VbgdDarwinErr2DarwinErr(int rc);
     96
     97static IOReturn         VbgdDarwinSleepHandler(void *pvTarget, void *pvRefCon, UInt32 uMessageType, IOService *pProvider, void *pvMessageArgument, vm_size_t argSize);
    10498RT_C_DECLS_END
    105 
    106 static void             vboxdrvDarwinResolveSymbols(void);
    10799
    108100
     
    111103*******************************************************************************/
    112104/**
    113  * The service class.
    114  * This is just a formality really.
    115  */
    116 class org_virtualbox_SupDrv : public IOService
    117 {
    118     OSDeclareDefaultStructors(org_virtualbox_SupDrv);
     105 * The service class for handling the VMMDev PCI device.
     106 *
     107 * Instantiated when the module is loaded (and on PCI hotplugging?).
     108 */
     109class org_virtualbox_VBoxGuest : public IOService
     110{
     111    OSDeclareDefaultStructors(org_virtualbox_VBoxGuest);
     112
     113private:
     114    IOPCIDevice                *m_pIOPCIDevice;
     115    IOMemoryMap                *m_pMap;
     116    IOFilterInterruptEventSource *m_pInterruptSrc;
     117
     118    bool setupVmmDevInterrupts(IOService *pProvider);
     119    bool disableVmmDevInterrupts(void);
     120    bool isVmmDev(IOPCIDevice *pIOPCIDevice);
    119121
    120122public:
    121     virtual bool init(OSDictionary *pDictionary = 0);
    122     virtual void free(void);
    123123    virtual bool start(IOService *pProvider);
    124124    virtual void stop(IOService *pProvider);
    125     virtual IOService *probe(IOService *pProvider, SInt32 *pi32Score);
    126125    virtual bool terminate(IOOptionBits fOptions);
    127126};
    128127
    129 OSDefineMetaClassAndStructors(org_virtualbox_SupDrv, IOService);
     128OSDefineMetaClassAndStructors(org_virtualbox_VBoxGuest, IOService);
    130129
    131130
     
    134133 * I don't think it'll work as I cannot figure out where/what creates the correct
    135134 * port right.
    136  */
    137 class org_virtualbox_SupDrvClient : public IOUserClient
    138 {
    139     OSDeclareDefaultStructors(org_virtualbox_SupDrvClient);
     135 *
     136 * Instantiated when userland does IOServiceOpen().
     137 */
     138class org_virtualbox_VBoxGuestClient : public IOUserClient
     139{
     140    OSDeclareDefaultStructors(org_virtualbox_VBoxGuestClient);
    140141
    141142private:
    142     PSUPDRVSESSION          m_pSession;     /**< The session. */
    143     task_t                  m_Task;         /**< The client task. */
    144     org_virtualbox_SupDrv  *m_pProvider;    /**< The service provider. */
     143    PVBOXGUESTSESSION           m_pSession;     /**< The session. */
     144    task_t                      m_Task;         /**< The client task. */
     145    org_virtualbox_VBoxGuest   *m_pProvider;    /**< The service provider. */
    145146
    146147public:
     
    149150    static  void sessionClose(RTPROCESS Process);
    150151    virtual IOReturn clientClose(void);
    151     virtual IOReturn clientDied(void);
    152     virtual bool terminate(IOOptionBits fOptions = 0);
    153     virtual bool finalize(IOOptionBits fOptions);
    154     virtual void stop(IOService *pProvider);
    155152};
    156153
    157 OSDefineMetaClassAndStructors(org_virtualbox_SupDrvClient, IOUserClient);
     154OSDefineMetaClassAndStructors(org_virtualbox_VBoxGuestClient, IOUserClient);
    158155
    159156
     
    169166extern kern_return_t _stop(struct kmod_info *pKModInfo, void *pvData);
    170167
    171 KMOD_EXPLICIT_DECL(VBoxDrv, VBOX_VERSION_STRING, _start, _stop)
    172 DECLHIDDEN(kmod_start_func_t *) _realmain = VBoxDrvDarwinStart;
    173 DECLHIDDEN(kmod_stop_func_t *)  _antimain = VBoxDrvDarwinStop;
     168KMOD_EXPLICIT_DECL(VBoxGuest, VBOX_VERSION_STRING, _start, _stop)
     169DECLHIDDEN(kmod_start_func_t *) _realmain = VbgdDarwinStart;
     170DECLHIDDEN(kmod_stop_func_t *)  _antimain = VbgdDarwinStop;
    174171DECLHIDDEN(int)                 _kext_apple_cc = __APPLE_CC__;
    175172RT_C_DECLS_END
     
    179176 * Device extention & session data association structure.
    180177 */
    181 static SUPDRVDEVEXT     g_DevExt;
     178static VBOXGUESTDEVEXT  g_DevExt;
    182179
    183180/**
     
    186183static struct cdevsw    g_DevCW =
    187184{
    188     /** @todo g++ doesn't like this syntax - it worked with gcc before renaming to .cpp. */
    189     /*.d_open  = */VBoxDrvDarwinOpen,
    190     /*.d_close = */VBoxDrvDarwinClose,
    191     /*.d_read  = */eno_rdwrt,
    192     /*.d_write = */eno_rdwrt,
    193     /*.d_ioctl = */VBoxDrvDarwinIOCtl,
    194     /*.d_stop  = */eno_stop,
    195     /*.d_reset = */eno_reset,
    196     /*.d_ttys  = */NULL,
    197     /*.d_select= */eno_select,
    198     /*.d_mmap  = */eno_mmap,
    199     /*.d_strategy = */eno_strat,
    200     /*.d_getc  = */eno_getc,
    201     /*.d_putc  = */eno_putc,
    202     /*.d_type  = */0
     185    /*.d_open     = */ VbgdDarwinOpen,
     186    /*.d_close    = */ VbgdDarwinClose,
     187    /*.d_read     = */ eno_rdwrt,
     188    /*.d_write    = */ eno_rdwrt,
     189    /*.d_ioctl    = */ VbgdDarwinIOCtl,
     190    /*.d_stop     = */ eno_stop,
     191    /*.d_reset    = */ eno_reset,
     192    /*.d_ttys     = */ NULL,
     193    /*.d_select   = */ eno_select,
     194    /*.d_mmap     = */ eno_mmap,
     195    /*.d_strategy = */ eno_strat,
     196    /*.d_getc     = */ eno_getc,
     197    /*.d_putc     = */ eno_putc,
     198    /*.d_type     = */ 0
    203199};
    204200
    205201/** Major device number. */
    206 static int              g_iMajorDeviceNo = -1;
    207 /** Registered devfs device handle for the system device. */
    208 static void            *g_hDevFsDeviceSys = NULL;
     202static int                  g_iMajorDeviceNo    = -1;
     203/** Registered devfs device handle. */
     204static void                *g_hDevFsDeviceSys  = NULL;
    209205/** Registered devfs device handle for the user device. */
    210 static void            *g_hDevFsDeviceUsr = NULL;
     206static void                *g_hDevFsDeviceUsr   = NULL; /**< @todo 4 later */
    211207
    212208/** Spinlock protecting g_apSessionHashTab. */
    213 static RTSPINLOCK       g_Spinlock = NIL_RTSPINLOCK;
     209static RTSPINLOCK           g_Spinlock          = NIL_RTSPINLOCK;
    214210/** Hash table */
    215 static PSUPDRVSESSION   g_apSessionHashTab[19];
     211static PVBOXGUESTSESSION    g_apSessionHashTab[19];
    216212/** Calculates the index into g_apSessionHashTab.*/
    217 #define SESSION_HASH(pid)     ((pid) % RT_ELEMENTS(g_apSessionHashTab))
     213#define SESSION_HASH(pid)   ((pid) % RT_ELEMENTS(g_apSessionHashTab))
    218214/** The number of open sessions. */
    219 static int32_t volatile g_cSessions = 0;
     215static int32_t volatile     g_cSessions         = 0;
     216/** The number of IOService class instances. */
     217static bool volatile        g_fInstantiated     = 0;
    220218/** The notifier handle for the sleep callback handler. */
    221 static IONotifier      *g_pSleepNotifier = NULL;
    222 
    223 /** Pointer to vmx_suspend(). */
    224 static PFNRT            g_pfnVmxSuspend = NULL;
    225 /** Pointer to vmx_resume(). */
    226 static PFNRT            g_pfnVmxResume = NULL;
    227 /** Pointer to vmx_use_count. */
    228 static int volatile    *g_pVmxUseCount = NULL;
     219static IONotifier          *g_pSleepNotifier    = NULL;
     220
    229221
    230222
     
    232224 * Start the kernel module.
    233225 */
    234 static kern_return_t    VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pvData)
    235 {
    236     int rc;
     226static kern_return_t    VbgdDarwinStart(struct kmod_info *pKModInfo, void *pvData)
     227{
    237228#ifdef DEBUG
    238     printf("VBoxDrvDarwinStart\n");
     229    printf("VbgdDarwinStart\n");
    239230#endif
    240231
     
    242233     * Initialize IPRT.
    243234     */
    244     rc = RTR0Init(0);
    245     if (RT_SUCCESS(rc))
    246     {
    247         /*
    248          * Initialize the device extension.
    249          */
    250         rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
    251         if (RT_SUCCESS(rc))
    252         {
    253             /*
    254              * Initialize the session hash table.
    255              */
    256             memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab)); /* paranoia */
    257             rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvDarwin");
    258             if (RT_SUCCESS(rc))
    259             {
    260                 /*
    261                  * Registering ourselves as a character device.
    262                  */
    263                 g_iMajorDeviceNo = cdevsw_add(-1, &g_DevCW);
    264                 if (g_iMajorDeviceNo >= 0)
    265                 {
    266 #ifdef VBOX_WITH_HARDENING
    267                     g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
    268                                                         UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME_SYS);
    269 #else
    270                     g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
    271                                                         UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
     235    int rc = RTR0Init(0);
     236    if (RT_FAILURE(rc))
     237    {
     238        printf("VBoxGuest: RTR0Init failed with rc=%d\n", rc);
     239        return KMOD_RETURN_FAILURE;
     240    }
     241
     242    return KMOD_RETURN_SUCCESS;
     243}
     244
     245
     246/* Register VBoxGuest char device */
     247static int VbgdDarwinCharDevInit(void)
     248{
     249    int rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestDarwin");
     250    if (RT_FAILURE(rc))
     251    {
     252        return KMOD_RETURN_FAILURE;
     253    }
     254
     255    /*
     256     * Registering ourselves as a character device.
     257     */
     258    g_iMajorDeviceNo = cdevsw_add(-1, &g_DevCW);
     259    if (g_iMajorDeviceNo < 0)
     260    {
     261        VbgdDarwinCharDevRemove();
     262        return KMOD_RETURN_FAILURE;
     263    }
     264
     265    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
     266                                        UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
     267    if (!g_hDevFsDeviceSys)
     268    {
     269        VbgdDarwinCharDevRemove();
     270        return KMOD_RETURN_FAILURE;
     271    }
     272
     273    /* Register a sleep/wakeup notification callback */
     274    g_pSleepNotifier = registerPrioritySleepWakeInterest(&VbgdDarwinSleepHandler, &g_DevExt, NULL);
     275    if (g_pSleepNotifier == NULL)
     276    {
     277        VbgdDarwinCharDevRemove();
     278        return KMOD_RETURN_FAILURE;
     279    }
     280
     281    return KMOD_RETURN_SUCCESS;
     282}
     283
     284
     285/**
     286 * Stop the kernel module.
     287 */
     288static kern_return_t VbgdDarwinStop(struct kmod_info *pKModInfo, void *pvData)
     289{
     290    RTR0TermForced();
     291#ifdef DEBUG
     292    printf("VbgdDarwinStop - done\n");
    272293#endif
    273                     if (g_hDevFsDeviceSys)
    274                     {
    275                         g_hDevFsDeviceUsr = devfs_make_node(makedev(g_iMajorDeviceNo, 1), DEVFS_CHAR,
    276                                                             UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_USR);
    277                         if (g_hDevFsDeviceUsr)
    278                         {
    279                             LogRel(("VBoxDrv: version " VBOX_VERSION_STRING " r%d; IOCtl version %#x; IDC version %#x; dev major=%d\n",
    280                                     VBOX_SVN_REV, SUPDRV_IOC_VERSION, SUPDRV_IDC_VERSION, g_iMajorDeviceNo));
    281 
    282                             /* Register a sleep/wakeup notification callback */
    283                             g_pSleepNotifier = registerPrioritySleepWakeInterest(&VBoxDrvDarwinSleepHandler, &g_DevExt, NULL);
    284                             if (g_pSleepNotifier == NULL)
    285                                 LogRel(("VBoxDrv: register for sleep/wakeup events failed\n"));
    286 
    287                             /* Find kernel symbols that are kind of optional. */
    288                             vboxdrvDarwinResolveSymbols();
    289                             return KMOD_RETURN_SUCCESS;
    290                         }
    291 
    292                         LogRel(("VBoxDrv: devfs_make_node(makedev(%d,1),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_USR));
    293                         devfs_remove(g_hDevFsDeviceSys);
    294                         g_hDevFsDeviceSys = NULL;
    295                     }
    296                     else
    297                         LogRel(("VBoxDrv: devfs_make_node(makedev(%d,0),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_SYS));
    298 
    299                     cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
    300                     g_iMajorDeviceNo = -1;
    301                 }
    302                 else
    303                     LogRel(("VBoxDrv: cdevsw_add failed (%d)\n", g_iMajorDeviceNo));
    304                 RTSpinlockDestroy(g_Spinlock);
    305                 g_Spinlock = NIL_RTSPINLOCK;
    306             }
    307             else
    308                 LogRel(("VBoxDrv: RTSpinlockCreate failed (rc=%d)\n", rc));
    309             supdrvDeleteDevExt(&g_DevExt);
    310         }
    311         else
    312             printf("VBoxDrv: failed to initialize device extension (rc=%d)\n", rc);
    313         RTR0TermForced();
    314     }
    315     else
    316         printf("VBoxDrv: failed to initialize IPRT (rc=%d)\n", rc);
    317 
    318     memset(&g_DevExt, 0, sizeof(g_DevExt));
    319     return KMOD_RETURN_FAILURE;
    320 }
    321 
    322 
    323 /**
    324  * Resolves kernel symbols we want (but may do without).
    325  */
    326 static void vboxdrvDarwinResolveSymbols(void)
    327 {
    328     RTDBGKRNLINFO hKrnlInfo;
    329     int rc = RTR0DbgKrnlInfoOpen(&hKrnlInfo, 0);
    330     if (RT_SUCCESS(rc))
    331     {
    332         /* The VMX stuff. */
    333         int rc1 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "vmx_resume", (void **)&g_pfnVmxResume);
    334         int rc2 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "vmx_suspend", (void **)&g_pfnVmxSuspend);
    335         int rc3 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "vmx_use_count", (void **)&g_pVmxUseCount);
    336         if (RT_SUCCESS(rc1) && RT_SUCCESS(rc2) && RT_SUCCESS(rc3))
    337         {
    338             LogRel(("VBoxDrv: vmx_resume=%p vmx_suspend=%p vmx_use_count=%p (%d) cr4=%#x\n",
    339                     g_pfnVmxResume, g_pfnVmxSuspend, g_pVmxUseCount, *g_pVmxUseCount, ASMGetCR4() ));
    340         }
    341         else
    342         {
    343             LogRel(("VBoxDrv: failed to resolve vmx stuff: vmx_resume=%Rrc vmx_suspend=%Rrc vmx_use_count=%Rrc", rc1, rc2, rc3));
    344             g_pfnVmxResume  = NULL;
    345             g_pfnVmxSuspend = NULL;
    346             g_pVmxUseCount  = NULL;
    347         }
    348 
    349         RTR0DbgKrnlInfoRelease(hKrnlInfo);
    350     }
    351     else
    352         LogRel(("VBoxDrv: Failed to open kernel symbols, rc=%Rrc\n", rc));
    353 }
    354 
    355 
    356 /**
    357  * Stop the kernel module.
    358  */
    359 static kern_return_t    VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvData)
    360 {
    361     int rc;
    362     LogFlow(("VBoxDrvDarwinStop\n"));
    363 
    364     /** @todo I've got a nagging feeling that we'll have to keep track of users and refuse
    365      * unloading if we're busy. Investigate and implement this! */
    366 
    367     /*
    368      * Undo the work done during start (in reverse order).
    369      */
     294    return KMOD_RETURN_SUCCESS;
     295}
     296
     297
     298/* Unregister VBoxGuest char device */
     299static int
     300VbgdDarwinCharDevRemove(void)
     301{
     302    int rc = KMOD_RETURN_SUCCESS;
     303
    370304    if (g_pSleepNotifier)
    371305    {
     
    374308    }
    375309
    376     devfs_remove(g_hDevFsDeviceUsr);
    377     g_hDevFsDeviceUsr = NULL;
    378 
    379     devfs_remove(g_hDevFsDeviceSys);
    380     g_hDevFsDeviceSys = NULL;
    381 
    382     rc = cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
    383     Assert(rc == g_iMajorDeviceNo);
    384     g_iMajorDeviceNo = -1;
    385 
    386     supdrvDeleteDevExt(&g_DevExt);
    387 
    388     rc = RTSpinlockDestroy(g_Spinlock);
    389     AssertRC(rc);
    390     g_Spinlock = NIL_RTSPINLOCK;
    391 
    392     RTR0TermForced();
    393 
    394     memset(&g_DevExt, 0, sizeof(g_DevExt));
    395 #ifdef DEBUG
    396     printf("VBoxDrvDarwinStop - done\n");
    397 #endif
    398     return KMOD_RETURN_SUCCESS;
    399 }
    400 
    401 
    402 /**
    403  * Device open. Called on open /dev/vboxdrv
     310    if (g_hDevFsDeviceSys)
     311    {
     312        devfs_remove(g_hDevFsDeviceSys);
     313        g_hDevFsDeviceSys = NULL;
     314    }
     315
     316    if (g_hDevFsDeviceUsr)
     317    {
     318        devfs_remove(g_hDevFsDeviceUsr);
     319        g_hDevFsDeviceUsr = NULL;
     320    }
     321
     322    if (g_iMajorDeviceNo != -1)
     323    {
     324        int rc2 = cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
     325        Assert(rc2 == g_iMajorDeviceNo);
     326        g_iMajorDeviceNo = -1;
     327    }
     328
     329    if (g_Spinlock != NIL_RTSPINLOCK)
     330    {
     331        int rc2 = RTSpinlockDestroy(g_Spinlock); AssertRC(rc2);
     332        g_Spinlock = NIL_RTSPINLOCK;
     333    }
     334
     335    return rc;
     336}
     337
     338
     339/**
     340 * Device open. Called on open /dev/vboxguest and (later) /dev/vboxguestu.
    404341 *
    405342 * @param   Dev         The device number.
     
    408345 * @param   pProcess    The process issuing this request.
    409346 */
    410 static int VBoxDrvDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
    411 {
    412 #ifdef DEBUG_DARWIN_GIP
    413     char szName[128];
    414     szName[0] = '\0';
    415     proc_name(proc_pid(pProcess), szName, sizeof(szName));
    416     Log(("VBoxDrvDarwinOpen: pid=%d '%s'\n", proc_pid(pProcess), szName));
    417 #endif
    418 
     347static int VbgdDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
     348{
    419349    /*
    420350     * Only two minor devices numbers are allowed.
     
    424354
    425355    /*
    426      * Find the session created by org_virtualbox_SupDrvClient, fail
     356     * Find the session created by org_virtualbox_VBoxGuestClient, fail
    427357     * if no such session, and mark it as opened. We set the uid & gid
    428358     * here too, since that is more straight forward at this point.
    429359     */
    430     const bool      fUnrestricted = minor(Dev) == 0;
    431     int             rc = VINF_SUCCESS;
    432     PSUPDRVSESSION  pSession = NULL;
    433     kauth_cred_t    pCred = kauth_cred_proc_ref(pProcess);
     360    //const bool          fUnrestricted = minor(Dev) == 0;
     361    int                 rc = VINF_SUCCESS;
     362    PVBOXGUESTSESSION   pSession = NULL;
     363    kauth_cred_t        pCred = kauth_cred_proc_ref(pProcess);
    434364    if (pCred)
    435365    {
    436 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
    437         RTUID           Uid = kauth_cred_getruid(pCred);
    438         RTGID           Gid = kauth_cred_getrgid(pCred);
    439 #else
    440         RTUID           Uid = pCred->cr_ruid;
    441         RTGID           Gid = pCred->cr_rgid;
    442 #endif
    443366        RTPROCESS       Process = RTProcSelf();
    444367        unsigned        iHash = SESSION_HASH(Process);
     
    453376            {
    454377                pSession->fOpened = true;
    455                 pSession->fUnrestricted = fUnrestricted;
    456                 pSession->Uid = Uid;
    457                 pSession->Gid = Gid;
     378                /*pSession->fUnrestricted = fUnrestricted; - later */
    458379            }
    459380            else
     
    475396        rc = VERR_INVALID_PARAMETER;
    476397
    477 #ifdef DEBUG_DARWIN_GIP
    478     OSDBGPRINT(("VBoxDrvDarwinOpen: pid=%d '%s' pSession=%p rc=%d\n", proc_pid(pProcess), szName, pSession, rc));
    479 #else
    480     Log(("VBoxDrvDarwinOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, proc_pid(pProcess)));
    481 #endif
    482     return VBoxDrvDarwinErr2DarwinErr(rc);
     398    Log(("VbgdDarwinOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, proc_pid(pProcess)));
     399    return VbgdDarwinErr2DarwinErr(rc);
    483400}
    484401
     
    487404 * Close device.
    488405 */
    489 static int VBoxDrvDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
    490 {
    491     Log(("VBoxDrvDarwinClose: pid=%d\n", (int)RTProcSelf()));
     406static int VbgdDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
     407{
     408    Log(("VbgdDarwinClose: pid=%d\n", (int)RTProcSelf()));
    492409    Assert(proc_pid(pProcess) == (int)RTProcSelf());
    493410
    494411    /*
    495      * Hand the session closing to org_virtualbox_SupDrvClient.
    496      */
    497     org_virtualbox_SupDrvClient::sessionClose(RTProcSelf());
     412     * Hand the session closing to org_virtualbox_VBoxGuestClient.
     413     */
     414    org_virtualbox_VBoxGuestClient::sessionClose(RTProcSelf());
    498415    return 0;
    499416}
     
    506423 * @param   Dev         The device number (major+minor).
    507424 * @param   iCmd        The IOCtl command.
    508  * @param   pData       Pointer to the data (if any it's a SUPDRVIOCTLDATA (kernel copy)).
     425 * @param   pData       Pointer to the data (if any it's a VBOXGUESTIOCTLDATA (kernel copy)).
    509426 * @param   fFlags      Flag saying we're a character device (like we didn't know already).
    510427 * @param   pProcess    The process issuing this request.
    511428 */
    512 static int VBoxDrvDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess)
    513 {
    514     const bool          fUnrestricted = minor(Dev) == 0;
     429static int VbgdDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess)
     430{
     431    //const bool          fUnrestricted = minor(Dev) == 0;
    515432    const RTPROCESS     Process = proc_pid(pProcess);
    516433    const unsigned      iHash = SESSION_HASH(Process);
    517     PSUPDRVSESSION      pSession;
     434    PVBOXGUESTSESSION   pSession;
    518435
    519436    /*
     
    522439    RTSpinlockAcquire(g_Spinlock);
    523440    pSession = g_apSessionHashTab[iHash];
    524     while (pSession && pSession->Process != Process && pSession->fUnrestricted == fUnrestricted && pSession->fOpened)
     441    while (pSession && pSession->Process != Process /*later: && pSession->fUnrestricted == fUnrestricted*/ && pSession->fOpened)
    525442        pSession = pSession->pNextHash;
    526443    RTSpinlockReleaseNoInts(g_Spinlock);
    527444    if (!pSession)
    528445    {
    529         OSDBGPRINT(("VBoxDrvDarwinIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#lx\n",
    530                     (int)Process, iCmd));
     446        Log(("VBoxDrvDarwinIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#lx\n",
     447             (int)Process, iCmd));
    531448        return EINVAL;
    532449    }
    533450
    534451    /*
    535      * Deal with the two high-speed IOCtl that takes it's arguments from
    536      * the session and iCmd, and only returns a VBox status code.
    537      */
    538     if (   (    iCmd == SUP_IOCTL_FAST_DO_RAW_RUN
    539             ||  iCmd == SUP_IOCTL_FAST_DO_HM_RUN
    540             ||  iCmd == SUP_IOCTL_FAST_DO_NOP)
    541         && fUnrestricted)
    542         return supdrvIOCtlFast(iCmd, *(uint32_t *)pData, &g_DevExt, pSession);
    543     return VBoxDrvDarwinIOCtlSlow(pSession, iCmd, pData, pProcess);
    544 }
    545 
    546 
    547 /**
    548  * Worker for VBoxDrvDarwinIOCtl that takes the slow IOCtl functions.
     452     * No high speed IOCtls here yet.
     453     */
     454
     455    return VbgdDarwinIOCtlSlow(pSession, iCmd, pData, pProcess);
     456}
     457
     458
     459/**
     460 * Worker for VbgdDarwinIOCtl that takes the slow IOCtl functions.
    549461 *
    550462 * @returns Darwin errno.
     
    552464 * @param pSession  The session.
    553465 * @param iCmd      The IOCtl command.
    554  * @param pData     Pointer to the kernel copy of the SUPDRVIOCTLDATA buffer.
     466 * @param pData     Pointer to the kernel copy of the data buffer.
    555467 * @param pProcess  The calling process.
    556468 */
    557 static int VBoxDrvDarwinIOCtlSlow(PSUPDRVSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess)
    558 {
    559     LogFlow(("VBoxDrvDarwinIOCtlSlow: pSession=%p iCmd=%p pData=%p pProcess=%p\n", pSession, iCmd, pData, pProcess));
     469static int VbgdDarwinIOCtlSlow(PVBOXGUESTSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess)
     470{
     471    LogFlow(("VbgdDarwinIOCtlSlow: pSession=%p iCmd=%p pData=%p pProcess=%p\n", pSession, iCmd, pData, pProcess));
    560472
    561473
     
    563475     * Buffered or unbuffered?
    564476     */
    565     PSUPREQHDR pHdr;
     477    void *pvReqData;
    566478    user_addr_t pUser = 0;
    567479    void *pvPageBuf = NULL;
     
    569481    if ((IOC_DIRMASK & iCmd) == IOC_INOUT)
    570482    {
    571         pHdr = (PSUPREQHDR)pData;
    572         if (RT_UNLIKELY(cbReq < sizeof(*pHdr)))
    573         {
    574             OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: cbReq=%#x < %#x; iCmd=%#lx\n", cbReq, (int)sizeof(*pHdr), iCmd));
    575             return EINVAL;
    576         }
    577         if (RT_UNLIKELY((pHdr->fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
    578         {
    579             OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: bad magic fFlags=%#x; iCmd=%#lx\n", pHdr->fFlags, iCmd));
    580             return EINVAL;
    581         }
    582         if (RT_UNLIKELY(    RT_MAX(pHdr->cbIn, pHdr->cbOut) != cbReq
    583                         ||  pHdr->cbIn < sizeof(*pHdr)
    584                         ||  pHdr->cbOut < sizeof(*pHdr)))
    585         {
    586             OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: max(%#x,%#x) != %#x; iCmd=%#lx\n", pHdr->cbIn, pHdr->cbOut, cbReq, iCmd));
    587             return EINVAL;
    588         }
     483        /*
     484         * Raw buffered request data, common code validates it.
     485         */
     486        pvReqData = pData;
    589487    }
    590488    else if ((IOC_DIRMASK & iCmd) == IOC_VOID && !cbReq)
     
    593491         * Get the header and figure out how much we're gonna have to read.
    594492         */
    595         SUPREQHDR Hdr;
     493        VBGLBIGREQ Hdr;
    596494        pUser = (user_addr_t)*(void **)pData;
    597495        int rc = copyin(pUser, &Hdr, sizeof(Hdr));
    598496        if (RT_UNLIKELY(rc))
    599497        {
    600             OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyin(%llx,Hdr,) -> %#x; iCmd=%#lx\n", (unsigned long long)pUser, rc, iCmd));
     498            Log(("VbgdDarwinIOCtlSlow: copyin(%llx,Hdr,) -> %#x; iCmd=%#lx\n", (unsigned long long)pUser, rc, iCmd));
    601499            return rc;
    602500        }
    603         if (RT_UNLIKELY((Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
    604         {
    605             OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: bad magic fFlags=%#x; iCmd=%#lx\n", Hdr.fFlags, iCmd));
     501        if (RT_UNLIKELY(Hdr.u32Magic != VBGLBIGREQ_MAGIC))
     502        {
     503            Log(("VbgdDarwinIOCtlSlow: bad magic u32Magic=%#x; iCmd=%#lx\n", Hdr.u32Magic, iCmd));
    606504            return EINVAL;
    607505        }
    608         cbReq = RT_MAX(Hdr.cbIn, Hdr.cbOut);
    609         if (RT_UNLIKELY(    Hdr.cbIn < sizeof(Hdr)
    610                         ||  Hdr.cbOut < sizeof(Hdr)
    611                         ||  cbReq > _1M*16))
    612         {
    613             OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: max(%#x,%#x); iCmd=%#lx\n", Hdr.cbIn, Hdr.cbOut, iCmd));
     506        cbReq = Hdr.cbData;
     507        if (RT_UNLIKELY(cbReq > _1M*16))
     508        {
     509            Log(("VbgdDarwinIOCtlSlow: %#x; iCmd=%#lx\n", Hdr.cbData, iCmd));
    614510            return EINVAL;
    615511        }
     512        pUser = Hdr.pvDataR3;
    616513
    617514        /*
    618515         * Allocate buffer and copy in the data.
    619516         */
    620         pHdr = (PSUPREQHDR)RTMemTmpAlloc(cbReq);
    621         if (!pHdr)
    622             pvPageBuf = pHdr = (PSUPREQHDR)IOMallocAligned(RT_ALIGN_Z(cbReq, PAGE_SIZE), 8);
    623         if (RT_UNLIKELY(!pHdr))
    624         {
    625             OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: failed to allocate buffer of %d bytes; iCmd=%#lx\n", cbReq, iCmd));
     517        pvReqData = RTMemTmpAlloc(cbReq);
     518        if (!pvReqData)
     519            pvPageBuf = pvReqData = IOMallocAligned(RT_ALIGN_Z(cbReq, PAGE_SIZE), 8);
     520        if (RT_UNLIKELY(!pvReqData))
     521        {
     522            Log(("VbgdDarwinIOCtlSlow: failed to allocate buffer of %d bytes; iCmd=%#lx\n", cbReq, iCmd));
    626523            return ENOMEM;
    627524        }
    628         rc = copyin(pUser, pHdr, Hdr.cbIn);
     525        rc = copyin(pUser, pvReqData, Hdr.cbData);
    629526        if (RT_UNLIKELY(rc))
    630527        {
    631             OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyin(%llx,%p,%#x) -> %#x; iCmd=%#lx\n",
    632                         (unsigned long long)pUser, pHdr, Hdr.cbIn, rc, iCmd));
     528            Log(("VbgdDarwinIOCtlSlow: copyin(%llx,%p,%#x) -> %#x; iCmd=%#lx\n",
     529                 (unsigned long long)pUser, pvReqData, Hdr.cbData, rc, iCmd));
    633530            if (pvPageBuf)
    634531                IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
    635532            else
    636                 RTMemTmpFree(pHdr);
     533                RTMemTmpFree(pvReqData);
    637534            return rc;
    638535        }
     
    640537    else
    641538    {
    642         Log(("VBoxDrvDarwinIOCtlSlow: huh? cbReq=%#x iCmd=%#lx\n", cbReq, iCmd));
     539        Log(("VbgdDarwinIOCtlSlow: huh? cbReq=%#x iCmd=%#lx\n", cbReq, iCmd));
    643540        return EINVAL;
    644541    }
     
    647544     * Process the IOCtl.
    648545     */
    649     int rc = supdrvIOCtl(iCmd, &g_DevExt, pSession, pHdr);
    650     if (RT_LIKELY(!rc))
     546    size_t cbReqRet = 0;
     547    int rc = VBoxGuestCommonIOCtl(iCmd, &g_DevExt, pSession, pvReqData, cbReq, &cbReqRet);
     548    if (RT_SUCCESS(rc))
    651549    {
    652550        /*
     
    655553        if (pUser)
    656554        {
    657             uint32_t cbOut = pHdr->cbOut;
    658             if (cbOut > cbReq)
     555            if (cbReqRet > cbReq)
    659556            {
    660                 OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbOut, cbReq, iCmd));
    661                 cbOut = cbReq;
     557                Log(("VbgdDarwinIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbReqRet, cbReq, iCmd));
     558                cbReqRet = cbReq;
    662559            }
    663             rc = copyout(pHdr, pUser, cbOut);
     560            rc = copyout(pvReqData, pUser, cbReqRet);
    664561            if (RT_UNLIKELY(rc))
    665                 OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyout(%p,%llx,%#x) -> %d; uCmd=%#lx!\n",
    666                             pHdr, (unsigned long long)pUser, cbOut, rc, iCmd));
     562                Log(("VbgdDarwinIOCtlSlow: copyout(%p,%llx,%#x) -> %d; uCmd=%#lx!\n",
     563                     pvReqData, (unsigned long long)pUser, cbReqRet, rc, iCmd));
    667564
    668565            /* cleanup */
     
    670567                IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
    671568            else
    672                 RTMemTmpFree(pHdr);
    673         }
     569                RTMemTmpFree(pvReqData);
     570        }
     571        else
     572            rc = 0;
    674573    }
    675574    else
     
    683582                IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
    684583            else
    685                 RTMemTmpFree(pHdr);
    686         }
    687 
    688         Log(("VBoxDrvDarwinIOCtlSlow: pid=%d iCmd=%lx pData=%p failed, rc=%d\n", proc_pid(pProcess), iCmd, (void *)pData, rc));
     584                RTMemTmpFree(pvReqData);
     585        }
     586
     587        Log(("VbgdDarwinIOCtlSlow: pid=%d iCmd=%lx pData=%p failed, rc=%d\n", proc_pid(pProcess), iCmd, (void *)pData, rc));
    689588        rc = EINVAL;
    690589    }
    691590
    692     Log2(("VBoxDrvDarwinIOCtlSlow: returns %d\n", rc));
     591    Log2(("VbgdDarwinIOCtlSlow: returns %d\n", rc));
    693592    return rc;
    694593}
    695594
    696595
    697 /**
    698  * The SUPDRV IDC entry point.
    699  *
    700  * @returns VBox status code, see supdrvIDC.
    701  * @param   iReq        The request code.
    702  * @param   pReq        The request.
    703  */
    704 DECLEXPORT(int) VBOXCALL SUPDrvDarwinIDC(uint32_t uReq, PSUPDRVIDCREQHDR pReq)
    705 {
    706     PSUPDRVSESSION  pSession;
    707 
    708     /*
    709      * Some quick validations.
    710      */
    711     if (RT_UNLIKELY(!VALID_PTR(pReq)))
    712         return VERR_INVALID_POINTER;
    713 
    714     pSession = pReq->pSession;
    715     if (pSession)
    716     {
    717         if (RT_UNLIKELY(!VALID_PTR(pSession)))
    718             return VERR_INVALID_PARAMETER;
    719         if (RT_UNLIKELY(pSession->pDevExt != &g_DevExt))
    720             return VERR_INVALID_PARAMETER;
    721     }
    722     else if (RT_UNLIKELY(uReq != SUPDRV_IDC_REQ_CONNECT))
    723         return VERR_INVALID_PARAMETER;
    724 
    725     /*
    726      * Do the job.
    727      */
    728     return supdrvIDC(uReq, &g_DevExt, pSession, pReq);
    729 }
    730 
    731 
    732 /**
    733  * Initializes any OS specific object creator fields.
    734  */
    735 void VBOXCALL   supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession)
    736 {
    737     NOREF(pObj);
    738     NOREF(pSession);
    739 }
    740 
    741 
    742 /**
    743  * Checks if the session can access the object.
    744  *
    745  * @returns true if a decision has been made.
    746  * @returns false if the default access policy should be applied.
    747  *
    748  * @param   pObj        The object in question.
    749  * @param   pSession    The session wanting to access the object.
    750  * @param   pszObjName  The object name, can be NULL.
    751  * @param   prc         Where to store the result when returning true.
    752  */
    753 bool VBOXCALL   supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc)
    754 {
    755     NOREF(pObj);
    756     NOREF(pSession);
    757     NOREF(pszObjName);
    758     NOREF(prc);
    759     return false;
    760 }
     596/*
     597 * The VBoxGuest IDC entry points.
     598 *
     599 * This code is shared with the other unixy OSes.
     600 */
     601#include "VBoxGuestIDC-unix.c.h"
     602
     603
     604void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
     605{
     606    NOREF(pDevExt);
     607}
     608
    761609
    762610/**
    763611 * Callback for blah blah blah.
    764612 */
    765 IOReturn VBoxDrvDarwinSleepHandler(void * /* pvTarget */, void *pvRefCon, UInt32 uMessageType, IOService * /* pProvider */, void * /* pvMessageArgument */, vm_size_t /* argSize */)
    766 {
    767     LogFlow(("VBoxDrv: Got sleep/wake notice. Message type was %X\n", (uint)uMessageType));
     613IOReturn VbgdDarwinSleepHandler(void * /* pvTarget */, void *pvRefCon, UInt32 uMessageType, IOService * /* pProvider */, void * /* pvMessageArgument */, vm_size_t /* argSize */)
     614{
     615    LogFlow(("VBoxGuest: Got sleep/wake notice. Message type was %X\n", (uint)uMessageType));
    768616
    769617    if (uMessageType == kIOMessageSystemWillSleep)
     
    779627
    780628/**
    781  * @copydoc SUPR0EnableVTx
    782  */
    783 int VBOXCALL supdrvOSEnableVTx(bool fEnable)
    784 {
    785 #ifdef VBOX_WITH_HOST_VMX
    786     int rc;
    787     if (   version_major >= 10 /* 10 = 10.6.x = Snow Leopard */
    788         && g_pfnVmxSuspend
    789         && g_pfnVmxResume
    790         && g_pVmxUseCount)
    791     {
    792         if (fEnable)
    793         {
    794             rc = host_vmxon(false /* exclusive */);
    795             if (rc == VMX_OK)
    796                 rc = VINF_SUCCESS;
    797             else if (rc == VMX_UNSUPPORTED)
    798                 rc = VERR_VMX_NO_VMX;
    799             else if (rc == VMX_INUSE)
    800                 rc = VERR_VMX_IN_VMX_ROOT_MODE;
    801             else /* shouldn't happen, but just in case. */
    802             {
    803                 LogRel(("host_vmxon returned %d\n", rc));
    804                 rc = VERR_UNRESOLVED_ERROR;
    805             }
    806             LogRel(("VBoxDrv: host_vmxon  -> vmx_use_count=%d rc=%Rrc\n", *g_pVmxUseCount, rc));
    807         }
    808         else
    809         {
    810             host_vmxoff();
    811             rc = VINF_SUCCESS;
    812             LogRel(("VBoxDrv: host_vmxoff -> vmx_use_count=%d\n", *g_pVmxUseCount));
    813         }
    814     }
    815     else
    816     {
    817         /* In 10.5.x the host_vmxon is severely broken!  Don't use it, it will
    818            frequnetly panic the host. */
    819         rc = VERR_NOT_SUPPORTED;
    820     }
    821     return rc;
    822 #else
    823     return VERR_NOT_SUPPORTED;
    824 #endif
    825 }
    826 
    827 
    828 /**
    829  * @copydoc SUPR0SuspendVTxOnCpu
    830  */
    831 bool VBOXCALL supdrvOSSuspendVTxOnCpu(void)
    832 {
    833 #ifdef VBOX_WITH_HOST_VMX
    834     /*
    835      * Consult the VMX usage counter, don't try suspend if not enabled.
    836      *
    837      * Note!  The host_vmxon/off code is still race prone since, but this is
    838      *        currently the best we can do without always enable VMX when
    839      *        loading the driver.
    840      */
    841     if (   g_pVmxUseCount
    842         && *g_pVmxUseCount > 0)
    843     {
    844         g_pfnVmxSuspend();
    845         return true;
    846     }
    847     return false;
    848 #else
    849     return false;
    850 #endif
    851 }
    852 
    853 
    854 /**
    855  * @copydoc SUPR0ResumeVTxOnCpu
    856  */
    857 void VBOXCALL   supdrvOSResumeVTxOnCpu(bool fSuspended)
    858 {
    859 #ifdef VBOX_WITH_HOST_VMX
    860     /*
    861      * Don't consult the counter here, the state knows better.
    862      * We're executing with interrupts disabled and anyone racing us with
    863      * disabling VT-x will be waiting in the rendezvous code.
    864      */
    865     if (   fSuspended
    866         && g_pfnVmxResume)
    867         g_pfnVmxResume();
    868     else
    869         Assert(!fSuspended);
    870 #else
    871     Assert(!fSuspended);
    872 #endif
    873 }
    874 
    875 
    876 bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt)
    877 {
    878     NOREF(pDevExt);
    879     return false;
    880 }
    881 
    882 
    883 void VBOXCALL   supdrvOSLdrNotifyOpened(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
    884 {
    885 #if 1
    886     NOREF(pDevExt); NOREF(pImage);
    887 #else
    888     /*
    889      * Try store the image load address in NVRAM so we can retrived it on panic.
    890      * Note! This only works if you're root! - Acutally, it doesn't work at all at the moment. FIXME!
    891      */
    892     IORegistryEntry *pEntry = IORegistryEntry::fromPath("/options", gIODTPlane);
    893     if (pEntry)
    894     {
    895         char szVar[80];
    896         RTStrPrintf(szVar, sizeof(szVar), "vboximage"/*-%s*/, pImage->szName);
    897         char szValue[48];
    898         RTStrPrintf(szValue, sizeof(szValue), "%#llx,%#llx", (uint64_t)(uintptr_t)pImage->pvImage,
    899                     (uint64_t)(uintptr_t)pImage->pvImage + pImage->cbImageBits - 1);
    900         bool fRc = pEntry->setProperty(szVar, szValue); NOREF(fRc);
    901         pEntry->release();
    902         SUPR0Printf("fRc=%d '%s'='%s'\n", fRc, szVar, szValue);
    903     }
    904     /*else
    905         SUPR0Printf("failed to find /options in gIODTPlane\n");*/
    906 #endif
    907 }
    908 
    909 
    910 int  VBOXCALL   supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
    911 {
    912     NOREF(pDevExt); NOREF(pImage); NOREF(pszFilename);
    913     return VERR_NOT_SUPPORTED;
    914 }
    915 
    916 
    917 int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
    918 {
    919     NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits);
    920     return VERR_NOT_SUPPORTED;
    921 }
    922 
    923 
    924 int  VBOXCALL   supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
    925 {
    926     NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits); NOREF(pReq);
    927     return VERR_NOT_SUPPORTED;
    928 }
    929 
    930 
    931 void VBOXCALL   supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
    932 {
    933     NOREF(pDevExt); NOREF(pImage);
    934 }
    935 
    936 
    937 /**
    938629 * Converts an IPRT error code to a darwin error code.
    939630 *
     
    941632 * @param   rc      IPRT status code.
    942633 */
    943 static int VBoxDrvDarwinErr2DarwinErr(int rc)
     634static int VbgdDarwinErr2DarwinErr(int rc)
    944635{
    945636    switch (rc)
     
    961652
    962653
    963 RTDECL(int) SUPR0Printf(const char *pszFormat, ...)
    964 {
    965     va_list     va;
    966     char        szMsg[512];
    967 
    968     va_start(va, pszFormat);
    969     RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, va);
    970     va_end(va);
    971     szMsg[sizeof(szMsg) - 1] = '\0';
    972 
    973     printf("%s", szMsg);
    974     return 0;
    975 }
    976 
    977 
    978654/*
    979655 *
    980  * org_virtualbox_SupDrv
    981  *
    982  */
    983 
    984 
    985 /**
    986  * Initialize the object.
    987  */
    988 bool org_virtualbox_SupDrv::init(OSDictionary *pDictionary)
    989 {
    990     LogFlow(("org_virtualbox_SupDrv::init([%p], %p)\n", this, pDictionary));
    991     if (IOService::init(pDictionary))
    992     {
    993         /* init members. */
     656 * org_virtualbox_VBoxGuest
     657 *
     658 */
     659
     660static void
     661interruptHandler(OSObject *pOwner, IOInterruptEventSource *pSrc, int cInts)
     662{
     663    if (!pSrc)
     664        return;
     665
     666    bool fTaken = VBoxGuestCommonISR(&g_DevExt);
     667    if (!fTaken)
     668        printf("VBoxGuestCommonISR error\n");
     669}
     670
     671static bool
     672checkForInterrupt(OSObject *pOwner, IOFilterInterruptEventSource *pSrc)
     673{
     674    if (!pSrc)
     675        return false;
     676
     677    return true;
     678}
     679
     680bool
     681org_virtualbox_VBoxGuest::setupVmmDevInterrupts(IOService *pProvider)
     682{
     683    IOWorkLoop *pWorkLoop = (IOWorkLoop *)getWorkLoop();
     684
     685    if (!pWorkLoop)
     686        return false;
     687
     688    m_pInterruptSrc = IOFilterInterruptEventSource::filterInterruptEventSource(this,
     689                                                                               &interruptHandler,
     690                                                                               &checkForInterrupt,
     691                                                                               pProvider);
     692
     693    if (kIOReturnSuccess != pWorkLoop->addEventSource(m_pInterruptSrc))
     694    {
     695        m_pInterruptSrc->disable();
     696        m_pInterruptSrc->release();
     697        m_pInterruptSrc = 0;
     698        return false;
     699    }
     700
     701    m_pInterruptSrc->enable();
     702
     703    return true;
     704}
     705
     706bool
     707org_virtualbox_VBoxGuest::disableVmmDevInterrupts(void)
     708{
     709    IOWorkLoop *pWorkLoop = (IOWorkLoop *)getWorkLoop();
     710
     711    if (!pWorkLoop)
     712        return false;
     713
     714    if (!m_pInterruptSrc)
     715        return false;
     716
     717    m_pInterruptSrc->disable();
     718    pWorkLoop->removeEventSource(m_pInterruptSrc);
     719    m_pInterruptSrc->release();
     720    m_pInterruptSrc = 0;
     721
     722    return true;
     723}
     724
     725bool org_virtualbox_VBoxGuest::isVmmDev(IOPCIDevice *pIOPCIDevice)
     726{
     727    UInt16 uVendorId, uDeviceId;
     728
     729    if (!pIOPCIDevice)
     730        return false;
     731
     732    uVendorId = m_pIOPCIDevice->configRead16(kIOPCIConfigVendorID);
     733    uDeviceId = m_pIOPCIDevice->configRead16(kIOPCIConfigDeviceID);
     734
     735    if (uVendorId == VMMDEV_VENDORID && uDeviceId == VMMDEV_DEVICEID)
    994736        return true;
    995     }
     737
     738    return true;
     739}
     740
     741
     742/**
     743 * Start this service.
     744 */
     745bool org_virtualbox_VBoxGuest::start(IOService *pProvider)
     746{
     747    if (!IOService::start(pProvider))
     748        return false;
     749
     750    /* Low level initialization should be performed only once */
     751    if (!ASMAtomicCmpXchgBool(&g_fInstantiated, true, false))
     752    {
     753        IOService::stop(pProvider);
     754        return false;
     755    }
     756
     757    m_pIOPCIDevice = OSDynamicCast(IOPCIDevice, pProvider);
     758    if (m_pIOPCIDevice)
     759    {
     760        if (isVmmDev(m_pIOPCIDevice))
     761        {
     762            /* Enable memory response from VMM device */
     763            m_pIOPCIDevice->setMemoryEnable(true);
     764            m_pIOPCIDevice->setIOEnable(true);
     765
     766            IOMemoryDescriptor *pMem = m_pIOPCIDevice->getDeviceMemoryWithIndex(0);
     767            if (pMem)
     768            {
     769                IOPhysicalAddress IOPortBasePhys = pMem->getPhysicalAddress();
     770                /* Check that returned value is from I/O port range (at least it is 16-bit lenght) */
     771                if((IOPortBasePhys >> 16) == 0)
     772                {
     773
     774                    RTIOPORT IOPortBase = (RTIOPORT)IOPortBasePhys;
     775                    void    *pvMMIOBase = NULL;
     776                    uint32_t cbMMIO     = 0;
     777                    m_pMap = m_pIOPCIDevice->mapDeviceMemoryWithIndex(1);
     778                    if (m_pMap)
     779                    {
     780                        pvMMIOBase = (void *)m_pMap->getVirtualAddress();
     781                        cbMMIO     = m_pMap->getLength();
     782                    }
     783
     784                    int rc = VBoxGuestInitDevExt(&g_DevExt,
     785                                                 IOPortBase,
     786                                                 pvMMIOBase,
     787                                                 cbMMIO,
     788#if ARCH_BITS == 64
     789                                                 VBOXOSTYPE_MacOS_x64,
     790#else
     791                                                 VBOXOSTYPE_MacOS,
     792#endif
     793                                                 0);
     794                    if (RT_SUCCESS(rc))
     795                    {
     796                        rc = VbgdDarwinCharDevInit();
     797                        if (rc == KMOD_RETURN_SUCCESS)
     798                        {
     799                            if (setupVmmDevInterrupts(pProvider))
     800                            {
     801                                /* register the service. */
     802                                registerService();
     803                                printf("VBoxGuest: Successfully started I/O kit class instance.\n");
     804                                return true;
     805                            }
     806
     807                            printf("VBoxGuest: Failed to set up interrupts\n");
     808                            VbgdDarwinCharDevRemove();
     809                        }
     810                        else
     811                            printf("VBoxGuest: Failed to initialize character device (rc=%d).\n", rc);
     812
     813                        VBoxGuestDeleteDevExt(&g_DevExt);
     814                    }
     815                    else
     816                        printf("VBoxGuest: Failed to initialize common code (rc=%d).\n", rc);
     817
     818                    if (m_pMap)
     819                    {
     820                        m_pMap->release();
     821                        m_pMap = NULL;
     822                    }
     823                }
     824            }
     825            else
     826                printf("VBoxGuest: The device missing is the I/O port range (#0).\n");
     827        }
     828        else
     829            printf("VBoxGuest: Not the VMMDev (%#x:%#x).\n",
     830                   m_pIOPCIDevice->configRead16(kIOPCIConfigVendorID), m_pIOPCIDevice->configRead16(kIOPCIConfigDeviceID));
     831    }
     832    else
     833        printf("VBoxGuest: Provider is not an instance of IOPCIDevice.\n");
     834
     835    ASMAtomicXchgBool(&g_fInstantiated, false);
     836
     837    IOService::stop(pProvider);
     838
    996839    return false;
    997840}
     
    999842
    1000843/**
    1001  * Free the object.
    1002  */
    1003 void org_virtualbox_SupDrv::free(void)
    1004 {
    1005     LogFlow(("IOService::free([%p])\n", this));
    1006     IOService::free();
    1007 }
    1008 
    1009 
    1010 /**
    1011  * Check if it's ok to start this service.
    1012  * It's always ok by us, so it's up to IOService to decide really.
    1013  */
    1014 IOService *org_virtualbox_SupDrv::probe(IOService *pProvider, SInt32 *pi32Score)
    1015 {
    1016     LogFlow(("org_virtualbox_SupDrv::probe([%p])\n", this));
    1017     return IOService::probe(pProvider, pi32Score);
    1018 }
    1019 
    1020 
    1021 /**
    1022  * Start this service.
    1023  */
    1024 bool org_virtualbox_SupDrv::start(IOService *pProvider)
    1025 {
    1026     LogFlow(("org_virtualbox_SupDrv::start([%p])\n", this));
    1027 
    1028     if (IOService::start(pProvider))
    1029     {
    1030         /* register the service. */
    1031         registerService();
    1032         return true;
    1033     }
    1034     return false;
    1035 }
    1036 
    1037 
    1038 /**
    1039844 * Stop this service.
    1040845 */
    1041 void org_virtualbox_SupDrv::stop(IOService *pProvider)
    1042 {
    1043     LogFlow(("org_virtualbox_SupDrv::stop([%p], %p)\n", this, pProvider));
     846void org_virtualbox_VBoxGuest::stop(IOService *pProvider)
     847{
     848    LogFlow(("org_virtualbox_VBoxGuest::stop([%p], %p)\n", this, pProvider));
     849
     850    AssertReturnVoid(ASMAtomicReadBool(&g_fInstantiated));
     851
     852    /* Low level termination should be performed only once */
     853    if (!disableVmmDevInterrupts())
     854        printf("vboxguest: unable to unregister interrupt handler\n");
     855
     856    VbgdDarwinCharDevRemove();
     857    VBoxGuestDeleteDevExt(&g_DevExt);
     858
     859    if (m_pMap)
     860    {
     861        m_pMap->release();
     862        m_pMap = NULL;
     863    }
     864
    1044865    IOService::stop(pProvider);
     866
     867    ASMAtomicWriteBool(&g_fInstantiated, false);
     868
     869    printf("vboxguest module unloaded\n");
    1045870}
    1046871
     
    1052877 * @param   fOptions        Flags.
    1053878 */
    1054 bool org_virtualbox_SupDrv::terminate(IOOptionBits fOptions)
     879bool org_virtualbox_VBoxGuest::terminate(IOOptionBits fOptions)
    1055880{
    1056881    bool fRc;
    1057     LogFlow(("org_virtualbox_SupDrv::terminate: reference_count=%d g_cSessions=%d (fOptions=%#x)\n",
     882    LogFlow(("org_virtualbox_VBoxGuest::terminate: reference_count=%d g_cSessions=%d (fOptions=%#x)\n",
    1058883             KMOD_INFO_NAME.reference_count, ASMAtomicUoReadS32(&g_cSessions), fOptions));
    1059884    if (    KMOD_INFO_NAME.reference_count != 0
     
    1069894/*
    1070895 *
    1071  * org_virtualbox_SupDrvClient
     896 * org_virtualbox_VBoxGuestClient
    1072897 *
    1073898 */
     
    1077902 * Initializer called when the client opens the service.
    1078903 */
    1079 bool org_virtualbox_SupDrvClient::initWithTask(task_t OwningTask, void *pvSecurityId, UInt32 u32Type)
    1080 {
    1081     LogFlow(("org_virtualbox_SupDrvClient::initWithTask([%p], %#x, %p, %#x) (cur pid=%d proc=%p)\n",
     904bool org_virtualbox_VBoxGuestClient::initWithTask(task_t OwningTask, void *pvSecurityId, UInt32 u32Type)
     905{
     906    LogFlow(("org_virtualbox_VBoxGuestClient::initWithTask([%p], %#x, %p, %#x) (cur pid=%d proc=%p)\n",
    1082907             this, OwningTask, pvSecurityId, u32Type, RTProcSelf(), RTR0ProcHandleSelf()));
    1083908    AssertMsg((RTR0PROCESS)OwningTask == RTR0ProcHandleSelf(), ("%p %p\n", OwningTask, RTR0ProcHandleSelf()));
     
    1099924 * Start the client service.
    1100925 */
    1101 bool org_virtualbox_SupDrvClient::start(IOService *pProvider)
    1102 {
    1103     LogFlow(("org_virtualbox_SupDrvClient::start([%p], %p) (cur pid=%d proc=%p)\n",
     926bool org_virtualbox_VBoxGuestClient::start(IOService *pProvider)
     927{
     928    LogFlow(("org_virtualbox_VBoxGuestClient::start([%p], %p) (cur pid=%d proc=%p)\n",
    1104929             this, pProvider, RTProcSelf(), RTR0ProcHandleSelf() ));
    1105930    AssertMsgReturn((RTR0PROCESS)m_Task == RTR0ProcHandleSelf(),
     
    1109934    if (IOUserClient::start(pProvider))
    1110935    {
    1111         m_pProvider = OSDynamicCast(org_virtualbox_SupDrv, pProvider);
     936        m_pProvider = OSDynamicCast(org_virtualbox_VBoxGuest, pProvider);
    1112937        if (m_pProvider)
    1113938        {
     
    1117942             * Create a new session.
    1118943             */
    1119             int rc = supdrvCreateSession(&g_DevExt, true /* fUser */, false /*fUnrestricted*/, &m_pSession);
     944            int rc = VBoxGuestCreateUserSession(&g_DevExt, &m_pSession);
    1120945            if (RT_SUCCESS(rc))
    1121946            {
    1122947                m_pSession->fOpened = false;
    1123                 /* The Uid, Gid and fUnrestricted fields are set on open. */
     948                /* The fUnrestricted field is set on open. */
    1124949
    1125950                /*
     
    1130955                RTSpinlockAcquire(g_Spinlock);
    1131956
    1132                 PSUPDRVSESSION pCur = g_apSessionHashTab[iHash];
     957                PVBOXGUESTSESSION pCur = g_apSessionHashTab[iHash];
    1133958                if (pCur && pCur->Process != m_pSession->Process)
    1134959                {
     
    1140965                    m_pSession->pNextHash = g_apSessionHashTab[iHash];
    1141966                    g_apSessionHashTab[iHash] = m_pSession;
    1142                     m_pSession->pvSupDrvClient = this;
     967                    m_pSession->pvVBoxGuestClient = this;
    1143968                    ASMAtomicIncS32(&g_cSessions);
    1144969                    rc = VINF_SUCCESS;
     
    1147972                    rc = VERR_ALREADY_LOADED;
    1148973
    1149                 RTSpinlockReleaseNoInts(g_Spinlock);
     974                RTSpinlockRelease(g_Spinlock);
    1150975                if (RT_SUCCESS(rc))
    1151976                {
    1152                     Log(("org_virtualbox_SupDrvClient::start: created session %p for pid %d\n", m_pSession, (int)RTProcSelf()));
     977                    Log(("org_virtualbox_VBoxGuestClient::start: created session %p for pid %d\n", m_pSession, (int)RTProcSelf()));
    1153978                    return true;
    1154979                }
    1155980
    1156                 LogFlow(("org_virtualbox_SupDrvClient::start: already got a session for this process (%p)\n", pCur));
    1157                 supdrvCloseSession(&g_DevExt, m_pSession);
     981                LogFlow(("org_virtualbox_VBoxGuestClient::start: already got a session for this process (%p)\n", pCur));
     982                VBoxGuestCloseSession(&g_DevExt, m_pSession);
    1158983            }
    1159984
    1160985            m_pSession = NULL;
    1161             LogFlow(("org_virtualbox_SupDrvClient::start: rc=%Rrc from supdrvCreateSession\n", rc));
     986            LogFlow(("org_virtualbox_VBoxGuestClient::start: rc=%Rrc from supdrvCreateSession\n", rc));
    1162987        }
    1163988        else
    1164             LogFlow(("org_virtualbox_SupDrvClient::start: %p isn't org_virtualbox_SupDrv\n", pProvider));
     989            LogFlow(("org_virtualbox_VBoxGuestClient::start: %p isn't org_virtualbox_VBoxGuest\n", pProvider));
    1165990    }
    1166991    return false;
     
    1171996 * Common worker for clientClose and VBoxDrvDarwinClose.
    1172997 */
    1173 /* static */ void org_virtualbox_SupDrvClient::sessionClose(RTPROCESS Process)
     998/* static */ void org_virtualbox_VBoxGuestClient::sessionClose(RTPROCESS Process)
    1174999{
    11751000    /*
     
    11771002     *
    11781003     * Note! Only one session per process. (Both start() and
    1179      * VBoxDrvDarwinOpen makes sure this is so.)
     1004     * VbgdDarwinOpen makes sure this is so.)
    11801005     */
    11811006    const unsigned  iHash = SESSION_HASH(Process);
    11821007    RTSpinlockAcquire(g_Spinlock);
    1183     PSUPDRVSESSION  pSession = g_apSessionHashTab[iHash];
     1008    PVBOXGUESTSESSION  pSession = g_apSessionHashTab[iHash];
    11841009    if (pSession)
    11851010    {
     
    11921017        else
    11931018        {
    1194             PSUPDRVSESSION pPrev = pSession;
     1019            PVBOXGUESTSESSION pPrev = pSession;
    11951020            pSession = pSession->pNextHash;
    11961021            while (pSession)
     
    12101035        }
    12111036    }
    1212     RTSpinlockReleaseNoInts(g_Spinlock);
     1037    RTSpinlockRelease(g_Spinlock);
    12131038    if (!pSession)
    12141039    {
    1215         Log(("SupDrvClient::sessionClose: pSession == NULL, pid=%d; freed already?\n", (int)Process));
     1040        Log(("VBoxGuestClient::sessionClose: pSession == NULL, pid=%d; freed already?\n", (int)Process));
    12161041        return;
    12171042    }
     
    12201045     * Remove it from the client object.
    12211046     */
    1222     org_virtualbox_SupDrvClient *pThis = (org_virtualbox_SupDrvClient *)pSession->pvSupDrvClient;
    1223     pSession->pvSupDrvClient = NULL;
     1047    org_virtualbox_VBoxGuestClient *pThis = (org_virtualbox_VBoxGuestClient *)pSession->pvVBoxGuestClient;
     1048    pSession->pvVBoxGuestClient = NULL;
    12241049    if (pThis)
    12251050    {
     
    12311056     * Close the session.
    12321057     */
    1233     supdrvCloseSession(&g_DevExt, pSession);
     1058    VBoxGuestCloseSession(&g_DevExt, pSession);
    12341059}
    12351060
     
    12381063 * Client exits normally.
    12391064 */
    1240 IOReturn org_virtualbox_SupDrvClient::clientClose(void)
    1241 {
    1242     LogFlow(("org_virtualbox_SupDrvClient::clientClose([%p]) (cur pid=%d proc=%p)\n", this, RTProcSelf(), RTR0ProcHandleSelf()));
     1065IOReturn org_virtualbox_VBoxGuestClient::clientClose(void)
     1066{
     1067    LogFlow(("org_virtualbox_VBoxGuestClient::clientClose([%p]) (cur pid=%d proc=%p)\n", this, RTProcSelf(), RTR0ProcHandleSelf()));
    12431068    AssertMsg((RTR0PROCESS)m_Task == RTR0ProcHandleSelf(), ("%p %p\n", m_Task, RTR0ProcHandleSelf()));
    12441069
     
    12611086}
    12621087
    1263 
    1264 /**
    1265  * The client exits abnormally / forgets to do cleanups. (logging)
    1266  */
    1267 IOReturn org_virtualbox_SupDrvClient::clientDied(void)
    1268 {
    1269     LogFlow(("org_virtualbox_SupDrvClient::clientDied([%p]) m_Task=%p R0Process=%p Process=%d\n",
    1270              this, m_Task, RTR0ProcHandleSelf(), RTProcSelf()));
    1271 
    1272     /* IOUserClient::clientDied() calls clientClose, so we'll just do the work there. */
    1273     return IOUserClient::clientDied();
    1274 }
    1275 
    1276 
    1277 /**
    1278  * Terminate the service (initiate the destruction). (logging)
    1279  */
    1280 bool org_virtualbox_SupDrvClient::terminate(IOOptionBits fOptions)
    1281 {
    1282     LogFlow(("org_virtualbox_SupDrvClient::terminate([%p], %#x)\n", this, fOptions));
    1283     return IOUserClient::terminate(fOptions);
    1284 }
    1285 
    1286 
    1287 /**
    1288  * The final stage of the client service destruction. (logging)
    1289  */
    1290 bool org_virtualbox_SupDrvClient::finalize(IOOptionBits fOptions)
    1291 {
    1292     LogFlow(("org_virtualbox_SupDrvClient::finalize([%p], %#x)\n", this, fOptions));
    1293     return IOUserClient::finalize(fOptions);
    1294 }
    1295 
    1296 
    1297 /**
    1298  * Stop the client service. (logging)
    1299  */
    1300 void org_virtualbox_SupDrvClient::stop(IOService *pProvider)
    1301 {
    1302     LogFlow(("org_virtualbox_SupDrvClient::stop([%p])\n", this));
    1303     IOUserClient::stop(pProvider);
    1304 }
    1305 
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp

    r44992 r45459  
    5555# endif
    5656#endif
    57 #if defined(RT_OS_SOLARIS)
     57#if defined(RT_OS_SOLARIS) || defined(RT_OS_DARWIN)
    5858# include <iprt/rand.h>
    5959#endif
     
    7777static const size_t cbChangeMemBalloonReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]);
    7878
    79 #if defined(RT_OS_SOLARIS)
     79#if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
    8080/**
    8181 * Drag in the rest of IRPT since we share it with the
     
    9797    NULL
    9898};
    99 #endif  /* RT_OS_SOLARIS */
     99#endif  /* RT_OS_DARWIN || RT_OS_SOLARIS */
    100100
    101101
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h

    r44992 r45459  
    195195typedef struct VBOXGUESTSESSION
    196196{
    197 #if defined(RT_OS_OS2) || defined(RT_OS_FREEBSD) || defined(RT_OS_SOLARIS)
     197#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
    198198    /** Pointer to the next session with the same hash. */
    199199    PVBOXGUESTSESSION           pNextHash;
     
    224224     * be enabled for the host. */
    225225    uint32_t volatile           fMouseStatus;
    226 
     226#ifdef RT_OS_DARWIN
     227    /** Pointer to the associated org_virtualbox_VBoxGuestClient object. */
     228    void                       *pvVBoxGuestClient;
     229    /** Whether this session has been opened or not. */
     230    bool                        fOpened;
     231#endif
    227232} VBOXGUESTSESSION;
    228233
  • trunk/src/VBox/Additions/common/VBoxGuest/darwin/Info.plist

    r45447 r45459  
    11<?xml version="1.0" encoding="UTF-8"?>
    2 <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
     2<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    33<plist version="1.0">
    44<dict>
    55    <key>CFBundleDevelopmentRegion</key>        <string>English</string>
    6     <key>CFBundleExecutable</key>               <string>VBoxDrv</string>
    7     <key>CFBundleIdentifier</key>               <string>org.virtualbox.kext.VBoxDrv</string>
     6    <key>CFBundleExecutable</key>               <string>VBoxGuest</string>
     7    <key>CFBundleIdentifier</key>               <string>org.virtualbox.kext.VBoxGuest</string>
    88    <key>CFBundleInfoDictionaryVersion</key>    <string>6.0</string>
    9     <key>CFBundleName</key>                     <string>VBoxDrv</string>
     9    <key>CFBundleName</key>                     <string>VBoxGuest</string>
    1010    <key>CFBundlePackageType</key>              <string>KEXT</string>
    1111    <key>CFBundleSignature</key>                <string>????</string>
     12    <key>NSHumanReadableCopyright</key>         <string>Copyright © 2007-@VBOX_C_YEAR@ @VBOX_VENDOR@</string>
    1213    <key>CFBundleGetInfoString</key>            <string>@VBOX_PRODUCT@ @VBOX_VERSION_STRING@, © 2007-@VBOX_C_YEAR@ @VBOX_VENDOR@</string>
    1314    <key>CFBundleVersion</key>                  <string>@VBOX_VERSION_MAJOR@.@VBOX_VERSION_MINOR@.@VBOX_VERSION_BUILD@</string>
     
    1617    <key>IOKitPersonalities</key>
    1718    <dict>
    18         <key>VBoxDrv</key>
     19        <key>VBoxGuest</key>
    1920        <dict>
    20             <key>CFBundleIdentifier</key>       <string>org.virtualbox.kext.VBoxDrv</string>
    21             <key>IOClass</key>                  <string>org_virtualbox_SupDrv</string>
    22             <key>IOMatchCategory</key>          <string>org_virtualbox_SupDrv</string>
    23             <key>IOProviderClass</key>          <string>IOResources</string>
    24             <key>IOResourceMatch</key>          <string>IOKit</string>
    25             <key>IOUserClientClass</key>        <string>org_virtualbox_SupDrvClient</string>
     21            <key>CFBundleIdentifier</key>       <string>org.virtualbox.kext.VBoxGuest</string>
     22            <key>IOClass</key>                  <string>org_virtualbox_VBoxGuest</string>
     23            <key>IOMatchCategory</key>          <string>org_virtualbox_VBoxGuest</string>
     24            <key>IOUserClientClass</key>        <string>org_virtualbox_VBoxGuestClient</string>
     25            <key>IOKitDebug</key>               <integer>65535</integer>
     26            <key>IOProviderClass</key>          <string>IOPCIDevice</string>
     27            <key>IONameMatch</key>              <string>pci80ee,cafe</string>
    2628        </dict>
    2729    </dict>
    2830    <key>OSBundleLibraries</key>
    2931    <dict>
    30         <key>com.apple.kpi.bsd</key>            <string>9.0.0</string>
    31         <key>com.apple.kpi.mach</key>           <string>9.0.0</string>
    32         <key>com.apple.kpi.libkern</key>        <string>9.0.0</string>
    33         <key>com.apple.kpi.unsupported</key>    <string>9.0.0</string>
    34         <key>com.apple.kpi.iokit</key>          <string>9.0.0</string>
     32        <key>com.apple.iokit.IOPCIFamily</key>  <string>2.5</string> <!-- TODO: Figure the version in mac os x 10.4. -->
     33        <key>com.apple.kpi.bsd</key>            <string>8.0.0</string>
     34        <key>com.apple.kpi.mach</key>           <string>8.0.0</string>
     35        <key>com.apple.kpi.libkern</key>        <string>8.0.0</string>
     36        <key>com.apple.kpi.unsupported</key>    <string>8.0.0</string>
     37        <key>com.apple.kpi.iokit</key>          <string>8.0.0</string>
    3538    </dict>
    3639    <key>OSBundleLibraries_x86_64</key>
    3740    <dict>
     41        <key>com.apple.iokit.IOPCIFamily</key>  <string>2.6</string>
    3842        <key>com.apple.kpi.bsd</key>            <string>10.0.0d4</string>
    3943        <key>com.apple.kpi.mach</key>           <string>10.0.0d3</string>
  • trunk/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp

    r44528 r45459  
    5050/** The max parameter buffer size for a kernel request. */
    5151#define VBGLR0_MAX_HGCM_KERNEL_PARM     (16*_1M)
    52 #ifdef RT_OS_LINUX
     52#if defined(RT_OS_LINUX) || (defined(RT_OS_DARWIN) && defined(RT_ARCH_X86))
    5353/** Linux needs to use bounce buffers since RTR0MemObjLockUser has unwanted
    54  *  side effects. */
     54 * side effects.
     55 * Darwin 32bit also needs this because of 4GB/4GB user/kernel space. */
    5556# define USE_BOUNCE_BUFFERS
    5657#endif
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp

    r45356 r45459  
    3737# include <os2.h>
    3838
    39 #elif defined(RT_OS_FREEBSD) \
     39#elif defined(RT_OS_DARWIN) \
     40   || defined(RT_OS_FREEBSD) \
    4041   || defined(RT_OS_HAIKU) \
    4142   || defined(RT_OS_LINUX) \
     
    4344# include <sys/types.h>
    4445# include <sys/stat.h>
    45 # if defined(RT_OS_LINUX) /** @todo check this on solaris+freebsd as well. */
     46# if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) /** @todo check this on solaris+freebsd as well. */
    4647#  include <sys/ioctl.h>
     48# endif
     49# if defined(RT_OS_DARWIN)
     50#  include <mach/mach_port.h>
     51#  include <IOKit/IOKitLib.h>
    4752# endif
    4853# include <errno.h>
     
    8792 */
    8893static uint32_t volatile g_cInits = 0;
     94#ifdef RT_OS_DARWIN
     95/** I/O Kit connection handle. */
     96static io_connect_t g_uConnection = 0;
     97#endif
    8998
    9099
     
    191200    g_File = (RTFILE)hf;
    192201
     202#elif defined(RT_OS_DARWIN)
     203    /*
     204     * Darwin is kind of special we need to engage the device via I/O first
     205     * before we open it via the BSD device node.
     206     */
     207    mach_port_t MasterPort;
     208    kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort);
     209    if (kr != kIOReturnSuccess)
     210        return VERR_GENERAL_FAILURE;
     211
     212    CFDictionaryRef ClassToMatch = IOServiceMatching("org_virtualbox_VBoxGuest");
     213    if (!ClassToMatch)
     214        return VERR_GENERAL_FAILURE;
     215
     216    io_service_t ServiceObject = IOServiceGetMatchingService(kIOMasterPortDefault, ClassToMatch);
     217    if (!ServiceObject)
     218        return VERR_NOT_FOUND;
     219
     220    io_connect_t uConnection;
     221    kr = IOServiceOpen(ServiceObject, mach_task_self(), 0, &uConnection);
     222    IOObjectRelease(ServiceObject);
     223    if (kr != kIOReturnSuccess)
     224        return VERR_OPEN_FAILED;
     225
     226    RTFILE hFile;
     227    int rc = RTFileOpen(&hFile, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
     228    if (RT_FAILURE(rc))
     229    {
     230        IOServiceClose(uConnection);
     231        return rc;
     232    }
     233    g_File = hFile;
     234    g_uConnection = uConnection;
     235
    193236#elif defined(VBOX_VBGLR3_XFREE86)
    194237    int File = xf86open(pszDeviceName, XF86_O_RDWR);
     
    264307
    265308# elif defined(RT_OS_OS2)
    266 
    267309    RTFILE File = g_File;
    268310    g_File = NIL_RTFILE;
     
    270312    APIRET rc = DosClose((uintptr_t)File);
    271313    AssertMsg(!rc, ("%ld\n", rc));
     314
     315#elif defined(RT_OS_DARWIN)
     316    io_connect_t    uConnection = g_uConnection;
     317    RTFILE          hFile       = g_File;
     318    g_uConnection = 0;
     319    g_File        = NIL_RTFILE;
     320    kern_return_t kr = IOServiceClose(uConnection);
     321    AssertMsg(kr == kIOReturnSuccess, ("%#x (%d)\n", kr, kr));
     322    int rc = RTFileClose(hFile);
     323    AssertRC(rc);
    272324
    273325# else /* The IPRT case. */
     
    359411    return VINF_SUCCESS;
    360412
    361 #elif defined(RT_OS_LINUX)
     413#elif defined(RT_OS_DARWIN) || defined(RT_OS_LINUX)
    362414# ifdef VBOX_VBGLR3_XFREE86
    363415    int rc = xf86ioctl((int)g_File, iFunction, pvData);
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp

    r44528 r45459  
    2929*   Header Files                                                               *
    3030*******************************************************************************/
    31 #if defined(RT_OS_DARWIN)
    32 # error "PORTME"
    33 
    34 #elif defined(RT_OS_OS2)
     31#if defined(RT_OS_OS2)
    3532# define INCL_BASE
    3633# define INCL_ERRORS
     
    7471VBGLR3DECL(int) VbglR3Daemonize(bool fNoChDir, bool fNoClose)
    7572{
    76 #if defined(RT_OS_DARWIN)
    77 # error "PORTME"
    78 
    79 #elif defined(RT_OS_OS2)
     73#if defined(RT_OS_OS2)
    8074    PPIB pPib;
    8175    PTIB pTib;
  • trunk/src/VBox/Additions/common/VBoxService/Makefile.kmk

    r45017 r45459  
    120120        VBoxServiceClipboard-os2.cpp
    121121
     122VBoxService_LDFLAGS.darwin = -framework IOKit
     123
    122124VBoxService_LIBS        += \
    123125        $(VBOX_LIB_IPRT_GUEST_R3) \
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp

    r45356 r45459  
    4848#  include <net/if_arp.h>
    4949# endif
    50 # ifdef RT_OS_FREEBSD
     50# if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    5151#  include <ifaddrs.h> /* getifaddrs, freeifaddrs */
    5252#  include <net/if_dl.h> /* LLADDR */
     
    450450           && RT_SUCCESS(rc))
    451451    {
     452#ifdef RT_OS_DARWIN /* No ut_user->ut_session on Darwin */
     453        VBoxServiceVerbose(4, "Found entry \"%s\" (type: %d, PID: %RU32)\n",
     454                           ut_user->ut_user, ut_user->ut_type, ut_user->ut_pid);
     455#else
    452456        VBoxServiceVerbose(4, "Found entry \"%s\" (type: %d, PID: %RU32, session: %RU32)\n",
    453457                           ut_user->ut_user, ut_user->ut_type, ut_user->ut_pid, ut_user->ut_session);
     458#endif
    454459        if (cUsersInList > cListSize)
    455460        {
     
    908913    return VERR_NOT_IMPLEMENTED;
    909914
    910 #elif defined(RT_OS_FREEBSD)
     915#elif defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    911916    struct ifaddrs *pIfHead = NULL;
    912917
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette