/** @file * * VBoxGuestLib - A support library for VirtualBox guest additions: * Library initialization */ /* * Copyright (C) 2006-2007 Sun Microsystems, Inc. * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 USA or visit http://www.sun.com if you need * additional information or have any questions. */ #include #define VBGL_DECL_DATA #include "VBGLInternal.h" #include #include VBGLDATA g_vbgldata; #ifndef VBGL_VBOXGUEST /* The guest library uses lazy initialization for VMMDev port and memory, * because these values are provided by the VBoxGuest driver and it might * be loaded later than other drivers. * The VbglEnter checks the current library status, tries to retrive these * values and fails if they are unavailable. */ static void vbglQueryVMMDevPort (void) { int rc = VINF_SUCCESS; VBGLDRIVER driver; rc = vbglDriverOpen (&driver); if (RT_SUCCESS(rc)) { VBoxGuestPortInfo port; rc = vbglDriverIOCtl (&driver, VBOXGUEST_IOCTL_GETVMMDEVPORT, &port, sizeof (port)); if (RT_SUCCESS (rc)) { dprintf (("port = 0x%04X, mem = %p\n", port.portAddress, port.pVMMDevMemory)); g_vbgldata.portVMMDev = port.portAddress; g_vbgldata.pVMMDevMemory = port.pVMMDevMemory; g_vbgldata.status = VbglStatusReady; } vbglDriverClose (&driver); } dprintf (("vbglQueryVMMDevPort rc = %d\n", rc)); } #endif int VbglEnter (void) { int rc; #ifndef VBGL_VBOXGUEST if (g_vbgldata.status == VbglStatusInitializing) { vbglQueryVMMDevPort (); } #endif rc = g_vbgldata.status == VbglStatusReady? VINF_SUCCESS: VERR_VBGL_NOT_INITIALIZED; // dprintf(("VbglEnter: rc = %d\n", rc)); return rc; } int vbglInitCommon (void) { int rc = VINF_SUCCESS; memset(&g_vbgldata, 0, sizeof (VBGLDATA)); g_vbgldata.status = VbglStatusInitializing; rc = VbglPhysHeapInit (); if (RT_SUCCESS(rc)) { /* other subsystems, none yet */ ; } dprintf(("vbglInitCommon: rc = %d\n", rc)); return rc; } DECLVBGL(void) vbglTerminateCommon (void) { VbglPhysHeapTerminate (); memset(&g_vbgldata, 0, sizeof (VBGLDATA)); return; } #ifdef VBGL_VBOXGUEST DECLVBGL(int) VbglInit (VBGLIOPORT portVMMDev, VMMDevMemory *pVMMDevMemory) { int rc = VINF_SUCCESS; dprintf(("vbglInit: starts g_vbgldata.status %d\n", g_vbgldata.status)); if (g_vbgldata.status == VbglStatusInitializing || g_vbgldata.status == VbglStatusReady) { /* Initialization is already in process. */ return rc; } rc = vbglInitCommon (); if (RT_SUCCESS(rc)) { g_vbgldata.portVMMDev = portVMMDev; g_vbgldata.pVMMDevMemory = pVMMDevMemory; g_vbgldata.status = VbglStatusReady; } else { g_vbgldata.status = VbglStatusNotInitialized; } return rc; } DECLVBGL(void) VbglTerminate (void) { vbglTerminateCommon (); return; } #else /* !VBGL_VBOXGUEST */ DECLVBGL(int) VbglInit (void) { int rc = VINF_SUCCESS; if (g_vbgldata.status == VbglStatusInitializing || g_vbgldata.status == VbglStatusReady) { /* Initialization is already in process. */ return rc; } rc = vbglInitCommon (); if (RT_SUCCESS(rc)) { /* Try to obtain VMMDev port via IOCTL to VBoxGuest main driver. */ vbglQueryVMMDevPort (); #ifdef VBOX_WITH_HGCM rc = vbglHGCMInit (); #endif /* VBOX_WITH_HGCM */ if (RT_FAILURE(rc)) { vbglTerminateCommon (); } } return rc; } DECLVBGL(void) VbglTerminate (void) { vbglTerminateCommon (); #ifdef VBOX_WITH_HGCM vbglHGCMTerminate (); #endif return; } #endif /* !VBGL_VBOXGUEST */