VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuestLib/Init.cpp@ 56294

Last change on this file since 56294 was 56294, checked in by vboxsync, 10 years ago

Additions/common,Additions/os2: Updated (C) year.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.8 KB
Line 
1/* $Id: Init.cpp 56294 2015-06-09 14:26:20Z vboxsync $ */
2/** @file
3 * VBoxGuestLibR0 - Library initialization.
4 */
5
6/*
7 * Copyright (C) 2006-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#define VBGL_DECL_DATA
31#include "VBGLInternal.h"
32
33#include <iprt/string.h>
34#include <iprt/assert.h>
35#include <iprt/semaphore.h>
36
37/*******************************************************************************
38* Global Variables *
39*******************************************************************************/
40/** The global VBGL instance data. */
41VBGLDATA g_vbgldata;
42
43/**
44 * Used by vbglQueryDriverInfo and VbglInit to try get the host feature mask and
45 * version information (g_vbgldata::hostVersion).
46 *
47 * This was first implemented by the host in 3.1 and we quietly ignore failures
48 * for that reason.
49 */
50static void vbglR0QueryHostVersion (void)
51{
52 VMMDevReqHostVersion *pReq;
53
54 int rc = VbglGRAlloc ((VMMDevRequestHeader **) &pReq, sizeof (*pReq), VMMDevReq_GetHostVersion);
55
56 if (RT_SUCCESS (rc))
57 {
58 rc = VbglGRPerform (&pReq->header);
59
60 if (RT_SUCCESS (rc))
61 {
62 g_vbgldata.hostVersion = *pReq;
63 Log (("vbglR0QueryHostVersion: %u.%u.%ur%u %#x\n",
64 pReq->major, pReq->minor, pReq->build, pReq->revision, pReq->features));
65 }
66
67 VbglGRFree (&pReq->header);
68 }
69}
70
71#ifndef VBGL_VBOXGUEST
72/**
73 * The guest library uses lazy initialization for VMMDev port and memory,
74 * because these values are provided by the VBoxGuest driver and it might
75 * be loaded later than other drivers.
76 *
77 * The VbglEnter checks the current library status, tries to retrieve these
78 * values and fails if they are unavailable.
79 *
80 */
81static void vbglQueryDriverInfo (void)
82{
83 int rc = VINF_SUCCESS;
84
85 rc = RTSemMutexRequest(g_vbgldata.mutexDriverInit, RT_INDEFINITE_WAIT);
86
87 if (RT_FAILURE(rc))
88 return;
89
90 if (g_vbgldata.status == VbglStatusReady)
91 {
92 RTSemMutexRelease(g_vbgldata.mutexDriverInit);
93 return;
94 }
95
96 rc = vbglDriverOpen(&g_vbgldata.driver);
97
98 if (RT_SUCCESS(rc))
99 {
100 /*
101 * Try query the port info.
102 */
103 VBoxGuestPortInfo port;
104
105 rc = vbglDriverIOCtl (&g_vbgldata.driver,
106 VBOXGUEST_IOCTL_GETVMMDEVPORT, &port,
107 sizeof (port));
108
109 if (RT_SUCCESS (rc))
110 {
111 dprintf (("port = 0x%04X, mem = %p\n", port.portAddress, port.pVMMDevMemory));
112
113 g_vbgldata.portVMMDev = port.portAddress;
114 g_vbgldata.pVMMDevMemory = port.pVMMDevMemory;
115
116 g_vbgldata.status = VbglStatusReady;
117
118 vbglR0QueryHostVersion();
119 }
120 }
121 RTSemMutexRelease(g_vbgldata.mutexDriverInit);
122 dprintf (("vbglQueryDriverInfo rc = %d\n", rc));
123}
124#endif /* !VBGL_VBOXGUEST */
125
126/**
127 * Checks if VBGL has been initialized.
128 *
129 * The client library, this will lazily complete the initialization.
130 *
131 * @return VINF_SUCCESS or VERR_VBGL_NOT_INITIALIZED.
132 */
133int vbglR0Enter (void)
134{
135 int rc;
136
137#ifndef VBGL_VBOXGUEST
138 if (g_vbgldata.status == VbglStatusInitializing)
139 {
140 vbglQueryDriverInfo ();
141 }
142#endif
143
144 rc = g_vbgldata.status == VbglStatusReady? VINF_SUCCESS: VERR_VBGL_NOT_INITIALIZED;
145
146 // dprintf(("VbglEnter: rc = %d\n", rc));
147
148 return rc;
149}
150
151int vbglInitCommon (void)
152{
153 int rc = VINF_SUCCESS;
154
155 RT_ZERO(g_vbgldata);
156
157 g_vbgldata.status = VbglStatusInitializing;
158
159 rc = VbglPhysHeapInit ();
160
161 if (RT_SUCCESS(rc))
162 {
163 /* other subsystems, none yet */
164 ;
165 }
166 else
167 {
168 LogRel(("vbglInitCommon: VbglPhysHeapInit failed. rc=%Rrc\n", rc));
169 g_vbgldata.status = VbglStatusNotInitialized;
170 }
171
172 dprintf(("vbglInitCommon: rc = %d\n", rc));
173
174 return rc;
175}
176
177DECLVBGL(void) vbglTerminateCommon (void)
178{
179 VbglPhysHeapTerminate ();
180 g_vbgldata.status = VbglStatusNotInitialized;
181
182 return;
183}
184
185#ifdef VBGL_VBOXGUEST
186
187DECLVBGL(int) VbglInit (VBGLIOPORT portVMMDev, VMMDevMemory *pVMMDevMemory)
188{
189 int rc = VINF_SUCCESS;
190
191# ifdef RT_OS_WINDOWS /** @todo r=bird: this doesn't make sense. Is there something special going on on windows? */
192 dprintf(("vbglInit: starts g_vbgldata.status %d\n", g_vbgldata.status));
193
194 if (g_vbgldata.status == VbglStatusInitializing
195 || g_vbgldata.status == VbglStatusReady)
196 {
197 /* Initialization is already in process. */
198 return rc;
199 }
200# else
201 dprintf(("vbglInit: starts\n"));
202# endif
203
204 rc = vbglInitCommon ();
205
206 if (RT_SUCCESS(rc))
207 {
208 g_vbgldata.portVMMDev = portVMMDev;
209 g_vbgldata.pVMMDevMemory = pVMMDevMemory;
210
211 g_vbgldata.status = VbglStatusReady;
212
213 vbglR0QueryHostVersion();
214 }
215 else
216 {
217 g_vbgldata.status = VbglStatusNotInitialized;
218 }
219
220 return rc;
221}
222
223DECLVBGL(void) VbglTerminate (void)
224{
225 vbglTerminateCommon ();
226
227 return;
228}
229
230
231#else /* !VBGL_VBOXGUEST */
232
233DECLVBGL(int) VbglInit (void)
234{
235 int rc = VINF_SUCCESS;
236
237 if (g_vbgldata.status == VbglStatusInitializing
238 || g_vbgldata.status == VbglStatusReady)
239 {
240 /* Initialization is already in process. */
241 return rc;
242 }
243
244 rc = vbglInitCommon ();
245
246 if (RT_SUCCESS(rc))
247 {
248 rc = RTSemMutexCreate(&g_vbgldata.mutexDriverInit);
249 if (RT_SUCCESS(rc))
250 {
251 /* Try to obtain VMMDev port via IOCTL to VBoxGuest main driver. */
252 vbglQueryDriverInfo ();
253
254# ifdef VBOX_WITH_HGCM
255 rc = vbglR0HGCMInit ();
256# endif /* VBOX_WITH_HGCM */
257
258 if (RT_FAILURE(rc))
259 {
260 RTSemMutexDestroy(g_vbgldata.mutexDriverInit);
261 g_vbgldata.mutexDriverInit = NIL_RTSEMMUTEX;
262 }
263 }
264
265 if (RT_FAILURE(rc))
266 {
267 vbglTerminateCommon ();
268 }
269
270 }
271
272 return rc;
273}
274
275DECLVBGL(void) VbglTerminate (void)
276{
277# ifdef VBOX_WITH_HGCM
278 vbglR0HGCMTerminate ();
279# endif
280
281 /* driver open could fail, which does not prevent VbglInit from succeeding,
282 * close the driver only if it is opened */
283 if (vbglDriverIsOpened(&g_vbgldata.driver))
284 vbglDriverClose(&g_vbgldata.driver);
285 RTSemMutexDestroy(g_vbgldata.mutexDriverInit);
286 g_vbgldata.mutexDriverInit = NIL_RTSEMMUTEX;
287
288 /* note: do vbglTerminateCommon as a last step since it zeroez up the g_vbgldata
289 * conceptually, doing vbglTerminateCommon last is correct
290 * since this is the reverse order to how init is done */
291 vbglTerminateCommon ();
292
293 return;
294}
295
296int vbglGetDriver(VBGLDRIVER **ppDriver)
297{
298 if (g_vbgldata.status != VbglStatusReady)
299 {
300 vbglQueryDriverInfo();
301 if (g_vbgldata.status != VbglStatusReady)
302 return VERR_TRY_AGAIN;
303 }
304 *ppDriver = &g_vbgldata.driver;
305 return VINF_SUCCESS;
306}
307
308#endif /* !VBGL_VBOXGUEST */
Note: See TracBrowser for help on using the repository browser.

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