Esempio n. 1
0
/**
 * Unload the driver.
 *
 * @param   pDrvObj     Driver object.
 */
void _stdcall VBoxDrvNtUnload(PDRIVER_OBJECT pDrvObj)
{
    PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pDrvObj->DeviceObject->DeviceExtension;

    Log(("VBoxDrvNtUnload at irql %d\n", KeGetCurrentIrql()));

    /* Clean up the power callback registration. */
    if (pDevExt->hPowerCallback)
        ExUnregisterCallback(pDevExt->hPowerCallback);
    if (pDevExt->pObjPowerCallback)
        ObDereferenceObject(pDevExt->pObjPowerCallback);

    /*
     * We ASSUME that it's not possible to unload a driver with open handles.
     * Start by deleting the symbolic link
     */
    UNICODE_STRING DosName;
    RtlInitUnicodeString(&DosName, DEVICE_NAME_DOS);
    NTSTATUS rc = IoDeleteSymbolicLink(&DosName);

    /*
     * Terminate the GIP page and delete the device extension.
     */
    supdrvDeleteDevExt(pDevExt);
    RTR0Term();
    IoDeleteDevice(pDrvObj->DeviceObject);
}
Esempio n. 2
0
/**
 * 32-bit Ring-0 initialization.
 *
 * @returns 0 on success, non-zero on failure.
 * @param   pszArgs     Pointer to the device arguments.
 */
DECLASM(int) VBoxDrvInit(const char *pszArgs)
{
    /*
     * Initialize the runtime.
     */
    int rc = RTR0Init(0);
    if (RT_SUCCESS(rc))
    {
        Log(("VBoxDrvInit: pszArgs=%s\n", pszArgs));

        /*
         * Initialize the device extension.
         */
        rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
        if (RT_SUCCESS(rc))
        {
            /*
             * Initialize the session hash table.
             */
            rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvOS2");
            if (RT_SUCCESS(rc))
            {
                /*
                 * Process the commandline. Later.
                 */
                bool fVerbose = true;

                /*
                 * Success
                 */
                if (fVerbose)
                {
                    strcpy(&g_szInitText[0],
                           "\r\n"
                           "VirtualBox.org Support Driver for OS/2 version " VBOX_VERSION_STRING "\r\n"
                           "Copyright (C) 2007 Knut St. Osmundsen\r\n"
                           "Copyright (C) 2007 Oracle Corporation\r\n");
                    g_cchInitText = strlen(&g_szInitText[0]);
                }
                return VINF_SUCCESS;
            }
            g_cchInitText = RTStrPrintf(&g_szInitText[0], g_cchInitTextMax, "VBoxDrv.sys: RTSpinlockCreate failed, rc=%Rrc\n", rc);
            supdrvDeleteDevExt(&g_DevExt);
        }
        else
            g_cchInitText = RTStrPrintf(&g_szInitText[0], g_cchInitTextMax, "VBoxDrv.sys: supdrvInitDevExt failed, rc=%Rrc\n", rc);
        RTR0Term();
    }
    else
        g_cchInitText = RTStrPrintf(&g_szInitText[0], g_cchInitTextMax, "VBoxDrv.sys: RTR0Init failed, rc=%Rrc\n", rc);
    return rc;
}
/**
 * Unload the module.
 */
static void __exit VBoxDrvLinuxUnload(void)
{
    int                 rc;
    Log(("VBoxDrvLinuxUnload\n"));
    NOREF(rc);

#ifdef VBOX_WITH_SUSPEND_NOTIFICATION
    platform_device_unregister(&gPlatformDevice);
    platform_driver_unregister(&gPlatformDriver);
#endif

    /*
     * I Don't think it's possible to unload a driver which processes have
     * opened, at least we'll blindly assume that here.
     */
#ifdef CONFIG_VBOXDRV_AS_MISC
    rc = misc_deregister(&gMiscDeviceUsr);
    if (rc < 0)
    {
        Log(("misc_deregister failed with rc=%#x on vboxdrvu\n", rc));
    }
    rc = misc_deregister(&gMiscDeviceSys);
    if (rc < 0)
    {
        Log(("misc_deregister failed with rc=%#x on vboxdrv\n", rc));
    }
#else  /* !CONFIG_VBOXDRV_AS_MISC */
# ifdef CONFIG_DEVFS_FS
    /*
     * Unregister a device entry
     */
    devfs_remove(DEVICE_NAME_USR);
    devfs_remove(DEVICE_NAME_SYS);
# endif /* devfs */
    unregister_chrdev(g_iModuleMajorUsr, DEVICE_NAME_USR);
    unregister_chrdev(g_iModuleMajorSys, DEVICE_NAME_SYS);
#endif /* !CONFIG_VBOXDRV_AS_MISC */

    /*
     * Destroy GIP, delete the device extension and terminate IPRT.
     */
    supdrvDeleteDevExt(&g_DevExt);
    RTR0TermForced();
}
Esempio n. 4
0
static int VBoxDrvFreeBSDLoad(void)
{
    g_cUsers = 0;

    /*
     * Initialize the runtime.
     */
    int rc = RTR0Init(0);
    if (RT_SUCCESS(rc))
    {
        Log(("VBoxDrvFreeBSDLoad:\n"));

        /*
         * Initialize the device extension.
         */
        rc = supdrvInitDevExt(&g_VBoxDrvFreeBSDDevExt, sizeof(SUPDRVSESSION));
        if (RT_SUCCESS(rc))
        {
            /*
             * Configure device cloning.
             */
            clone_setup(&g_pVBoxDrvFreeBSDClones);
            g_VBoxDrvFreeBSDEHTag = EVENTHANDLER_REGISTER(dev_clone, VBoxDrvFreeBSDClone, 0, 1000);
            if (g_VBoxDrvFreeBSDEHTag)
            {
                Log(("VBoxDrvFreeBSDLoad: returns successfully\n"));
                return VINF_SUCCESS;
            }

            printf("vboxdrv: EVENTHANDLER_REGISTER(dev_clone,,,) failed\n");
            clone_cleanup(&g_pVBoxDrvFreeBSDClones);
            rc = VERR_ALREADY_LOADED;
            supdrvDeleteDevExt(&g_VBoxDrvFreeBSDDevExt);
        }
        else
            printf("vboxdrv: supdrvInitDevExt failed, rc=%d\n", rc);
        RTR0Term();
    }
    else
        printf("vboxdrv: RTR0Init failed, rc=%d\n", rc);
    return rc;
}
static int VBoxDrvFreeBSDUnload(void)
{
    Log(("VBoxDrvFreeBSDUnload:\n"));

    if (g_cUsers > 0)
        return VERR_RESOURCE_BUSY;

    /*
     * Reserve what we did in VBoxDrvFreeBSDInit.
     */
    destroy_dev(g_pVBoxDrvFreeBSDChrDevUsr);
    destroy_dev(g_pVBoxDrvFreeBSDChrDevSys);

    supdrvDeleteDevExt(&g_VBoxDrvFreeBSDDevExt);

    RTR0TermForced();

    memset(&g_VBoxDrvFreeBSDDevExt, 0, sizeof(g_VBoxDrvFreeBSDDevExt));
    return VINF_SUCCESS;
}
Esempio n. 6
0
/**
 * Stop the kernel module.
 */
static kern_return_t    VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvData)
{
    int rc;
    LogFlow(("VBoxDrvDarwinStop\n"));

    /** @todo I've got a nagging feeling that we'll have to keep track of users and refuse
     * unloading if we're busy. Investigate and implement this! */

    /*
     * Undo the work done during start (in reverse order).
     */
    if (g_pSleepNotifier)
    {
        g_pSleepNotifier->remove();
        g_pSleepNotifier = NULL;
    }

    devfs_remove(g_hDevFsDeviceUsr);
    g_hDevFsDeviceUsr = NULL;

    devfs_remove(g_hDevFsDeviceSys);
    g_hDevFsDeviceSys = NULL;

    rc = cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
    Assert(rc == g_iMajorDeviceNo);
    g_iMajorDeviceNo = -1;

    supdrvDeleteDevExt(&g_DevExt);

    rc = RTSpinlockDestroy(g_Spinlock);
    AssertRC(rc);
    g_Spinlock = NIL_RTSPINLOCK;

    RTR0TermForced();

    memset(&g_DevExt, 0, sizeof(g_DevExt));
#ifdef DEBUG
    printf("VBoxDrvDarwinStop - done\n");
#endif
    return KMOD_RETURN_SUCCESS;
}
Esempio n. 7
0
/**
 * Unload the driver.
 *
 * @param   pDrvObj     Driver object.
 */
void _stdcall VBoxDrvNtUnload(PDRIVER_OBJECT pDrvObj)
{
    PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension;

    Log(("VBoxDrvNtUnload at irql %d\n", KeGetCurrentIrql()));

    /* Clean up the power callback registration. */
    if (pDevExt->hPowerCallback)
        ExUnregisterCallback(pDevExt->hPowerCallback);
    if (pDevExt->pObjPowerCallback)
        ObDereferenceObject(pDevExt->pObjPowerCallback);

    /*
     * We ASSUME that it's not possible to unload a driver with open handles.
     */
    supdrvDeleteDevExt(pDevExt);
    RTR0Term();
    vboxdrvNtDestroyDevices();

    NOREF(pDrvObj);
}
Esempio n. 8
0
static int VBoxDrvFreeBSDUnload(void)
{
    Log(("VBoxDrvFreeBSDUnload:\n"));

    if (g_cUsers > 0)
        return EBUSY;

    /*
     * Reserve what we did in VBoxDrvFreeBSDInit.
     */
    EVENTHANDLER_DEREGISTER(dev_clone, g_VBoxDrvFreeBSDEHTag);
    clone_cleanup(&g_pVBoxDrvFreeBSDClones);

    supdrvDeleteDevExt(&g_VBoxDrvFreeBSDDevExt);

    RTR0Term();

    memset(&g_VBoxDrvFreeBSDDevExt, 0, sizeof(g_VBoxDrvFreeBSDDevExt));

    Log(("VBoxDrvFreeBSDUnload: returns\n"));
    return VINF_SUCCESS;
}
int _fini(void)
{
    LogFlowFunc(("vboxdrv:_fini\n"));

    /*
     * Undo the work we did at start (in the reverse order).
     */
    int rc = mod_remove(&g_VBoxDrvSolarisModLinkage);
    if (rc != 0)
        return rc;

    supdrvDeleteDevExt(&g_DevExt);

    rc = RTSpinlockDestroy(g_Spinlock);
    AssertRC(rc);
    g_Spinlock = NIL_RTSPINLOCK;

    RTR0TermForced();

    memset(&g_DevExt, 0, sizeof(g_DevExt));

    ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
    return 0;
}
/**
 * Kernel entry points
 */
int _init(void)
{
#if 0    /* No IPRT logging before RTR0Init() is done! */
    LogFlowFunc(("vboxdrv:_init\n"));
#endif

    /*
     * Prevent module autounloading.
     */
    modctl_t *pModCtl = mod_getctl(&g_VBoxDrvSolarisModLinkage);
    if (pModCtl)
        pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
    else
        cmn_err(CE_NOTE, "vboxdrv: failed to disable autounloading!\n");

    /*
     * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
     */
    int rc = RTR0Init(0);
    if (RT_SUCCESS(rc))
    {
        /*
         * Initialize the device extension
         */
        rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
        if (RT_SUCCESS(rc))
        {
            cmn_err(CE_CONT, "!tsc::mode %s @ tentative %lu Hz\n", SUPGetGIPModeName(g_DevExt.pGip), g_DevExt.pGip->u64CpuHz);

            /*
             * Initialize the session hash table.
             */
            memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab));
            rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvSol");
            if (RT_SUCCESS(rc))
            {
                rc = ddi_soft_state_init(&g_pVBoxDrvSolarisState, sizeof(vbox_devstate_t), 8);
                if (!rc)
                {
                    rc = mod_install(&g_VBoxDrvSolarisModLinkage);
                    if (!rc)
                        return rc; /* success */

                    ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
                    LogRel(("vboxdrv: mod_install failed! rc=%d\n", rc));
                }
                else
                    LogRel(("vboxdrv: failed to initialize soft state.\n"));

                RTSpinlockDestroy(g_Spinlock);
                g_Spinlock = NIL_RTSPINLOCK;
            }
            else
            {
                LogRel(("VBoxDrvSolarisAttach: RTSpinlockCreate failed\n"));
                rc = RTErrConvertToErrno(rc);
            }
            supdrvDeleteDevExt(&g_DevExt);
        }
        else
        {
            LogRel(("VBoxDrvSolarisAttach: supdrvInitDevExt failed\n"));
            rc = EINVAL;
        }
        RTR0TermForced();
    }
    else
    {
        LogRel(("VBoxDrvSolarisAttach: failed to init R0Drv\n"));
        rc = RTErrConvertToErrno(rc);
    }
    memset(&g_DevExt, 0, sizeof(g_DevExt));

    return rc;
}
Esempio n. 11
0
/**
 * Start the kernel module.
 */
static kern_return_t    VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pvData)
{
    int rc;
#ifdef DEBUG
    printf("VBoxDrvDarwinStart\n");
#endif

    /*
     * Initialize IPRT.
     */
    rc = RTR0Init(0);
    if (RT_SUCCESS(rc))
    {
        /*
         * Initialize the device extension.
         */
        rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
        if (RT_SUCCESS(rc))
        {
            /*
             * Initialize the session hash table.
             */
            memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab)); /* paranoia */
            rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvDarwin");
            if (RT_SUCCESS(rc))
            {
                /*
                 * Registering ourselves as a character device.
                 */
                g_iMajorDeviceNo = cdevsw_add(-1, &g_DevCW);
                if (g_iMajorDeviceNo >= 0)
                {
#ifdef VBOX_WITH_HARDENING
                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
                                                        UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME_SYS);
#else
                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
                                                        UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
#endif
                    if (g_hDevFsDeviceSys)
                    {
                        g_hDevFsDeviceUsr = devfs_make_node(makedev(g_iMajorDeviceNo, 1), DEVFS_CHAR,
                                                            UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_USR);
                        if (g_hDevFsDeviceUsr)
                        {
                            LogRel(("VBoxDrv: version " VBOX_VERSION_STRING " r%d; IOCtl version %#x; IDC version %#x; dev major=%d\n",
                                    VBOX_SVN_REV, SUPDRV_IOC_VERSION, SUPDRV_IDC_VERSION, g_iMajorDeviceNo));

                            /* Register a sleep/wakeup notification callback */
                            g_pSleepNotifier = registerPrioritySleepWakeInterest(&VBoxDrvDarwinSleepHandler, &g_DevExt, NULL);
                            if (g_pSleepNotifier == NULL)
                                LogRel(("VBoxDrv: register for sleep/wakeup events failed\n"));

                            /* Find kernel symbols that are kind of optional. */
                            vboxdrvDarwinResolveSymbols();
                            return KMOD_RETURN_SUCCESS;
                        }

                        LogRel(("VBoxDrv: devfs_make_node(makedev(%d,1),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_USR));
                        devfs_remove(g_hDevFsDeviceSys);
                        g_hDevFsDeviceSys = NULL;
                    }
                    else
                        LogRel(("VBoxDrv: devfs_make_node(makedev(%d,0),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_SYS));

                    cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
                    g_iMajorDeviceNo = -1;
                }
                else
                    LogRel(("VBoxDrv: cdevsw_add failed (%d)\n", g_iMajorDeviceNo));
                RTSpinlockDestroy(g_Spinlock);
                g_Spinlock = NIL_RTSPINLOCK;
            }
            else
                LogRel(("VBoxDrv: RTSpinlockCreate failed (rc=%d)\n", rc));
            supdrvDeleteDevExt(&g_DevExt);
        }
        else
            printf("VBoxDrv: failed to initialize device extension (rc=%d)\n", rc);
        RTR0TermForced();
    }
    else
        printf("VBoxDrv: failed to initialize IPRT (rc=%d)\n", rc);

    memset(&g_DevExt, 0, sizeof(g_DevExt));
    return KMOD_RETURN_FAILURE;
}
Esempio n. 12
0
/**
 * Kernel entry points
 */
int _init(void)
{
    LogFlowFunc((DEVICE_NAME ":_init\n"));

    /*
     * Prevent module autounloading.
     */
    modctl_t *pModCtl = mod_getctl(&g_VBoxDrvSolarisModLinkage);
    if (pModCtl)
        pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
    else
        LogRel((DEVICE_NAME ":failed to disable autounloading!\n"));

    /*
     * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
     */
    int rc = RTR0Init(0);
    if (RT_SUCCESS(rc))
    {
        /*
         * Initialize the device extension
         */
        rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
        if (RT_SUCCESS(rc))
        {
            /*
             * Initialize the session hash table.
             */
            memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab));
            rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvSol");
            if (RT_SUCCESS(rc))
            {
                rc = ddi_soft_state_init(&g_pVBoxDrvSolarisState, sizeof(vbox_devstate_t), 8);
                if (!rc)
                {
                    rc = mod_install(&g_VBoxDrvSolarisModLinkage);
                    if (!rc)
                        return rc; /* success */

                    ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
                    LogRel((DEVICE_NAME ":mod_install failed! rc=%d\n", rc));
                }
                else
                    LogRel((DEVICE_NAME ":failed to initialize soft state.\n"));

                RTSpinlockDestroy(g_Spinlock);
                g_Spinlock = NIL_RTSPINLOCK;
            }
            else
            {
                LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: RTSpinlockCreate failed\n"));
                rc = RTErrConvertToErrno(rc);
            }
            supdrvDeleteDevExt(&g_DevExt);
        }
        else
        {
            LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: supdrvInitDevExt failed\n"));
            rc = RTErrConvertToErrno(rc);
        }
        RTR0TermForced();
    }
    else
    {
        LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: failed to init R0Drv\n"));
        rc = RTErrConvertToErrno(rc);
    }
    memset(&g_DevExt, 0, sizeof(g_DevExt));

    return rc;
}