VirtualBox

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

Last change on this file since 36638 was 34066, checked in by vboxsync, 14 years ago

Additions/common/VBoxGuestLib: don't leak HGCM handle during termination

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.3 KB
Line 
1/* $Revision: 34066 $ */
2/** @file
3 * VBoxGuestLibR0 - Library initialization.
4 */
5
6/*
7 * Copyright (C) 2006-2007 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
36/*******************************************************************************
37* Global Variables *
38*******************************************************************************/
39/** The global VBGL instance data. */
40VBGLDATA g_vbgldata;
41
42/**
43 * Used by vbglQueryVMMDevPort and VbglInit to try get the host feature mask and
44 * version information (g_vbgldata::hostVersion).
45 *
46 * This was first implemented by the host in 3.1 and we quietly ignore failures
47 * for that reason.
48 */
49static void vbglR0QueryHostVersion (void)
50{
51 VMMDevReqHostVersion *pReq;
52
53 int rc = VbglGRAlloc ((VMMDevRequestHeader **) &pReq, sizeof (*pReq), VMMDevReq_GetHostVersion);
54
55 if (RT_SUCCESS (rc))
56 {
57 rc = VbglGRPerform (&pReq->header);
58
59 if (RT_SUCCESS (rc))
60 {
61 g_vbgldata.hostVersion = *pReq;
62 Log (("vbglR0QueryHostVersion: %u.%u.%ur%u %#x\n",
63 pReq->major, pReq->minor, pReq->build, pReq->revision, pReq->features));
64 }
65
66 VbglGRFree (&pReq->header);
67 }
68}
69
70#ifndef VBGL_VBOXGUEST
71/**
72 * The guest library uses lazy initialization for VMMDev port and memory,
73 * because these values are provided by the VBoxGuest driver and it might
74 * be loaded later than other drivers.
75 *
76 * The VbglEnter checks the current library status, tries to retrieve these
77 * values and fails if they are unavailable.
78 *
79 */
80static void vbglQueryVMMDevPort (void)
81{
82 int rc = VINF_SUCCESS;
83
84 VBGLDRIVER driver;
85
86 rc = vbglDriverOpen (&driver);
87
88 if (RT_SUCCESS(rc))
89 {
90 /*
91 * Try query the port info.
92 */
93 VBoxGuestPortInfo port;
94
95 rc = vbglDriverIOCtl (&driver, VBOXGUEST_IOCTL_GETVMMDEVPORT, &port, sizeof (port));
96
97 if (RT_SUCCESS (rc))
98 {
99 dprintf (("port = 0x%04X, mem = %p\n", port.portAddress, port.pVMMDevMemory));
100
101 g_vbgldata.portVMMDev = port.portAddress;
102 g_vbgldata.pVMMDevMemory = port.pVMMDevMemory;
103
104 g_vbgldata.status = VbglStatusReady;
105
106 vbglR0QueryHostVersion();
107 }
108
109 vbglDriverClose (&driver);
110 }
111
112 dprintf (("vbglQueryVMMDevPort rc = %d\n", rc));
113}
114#endif /* !VBGL_VBOXGUEST */
115
116/**
117 * Checks if VBGL has been initialized.
118 *
119 * The the client library, this will lazily complete the initialization.
120 *
121 * @return VINF_SUCCESS or VERR_VBGL_NOT_INITIALIZED.
122 */
123int vbglR0Enter (void)
124{
125 int rc;
126
127#ifndef VBGL_VBOXGUEST
128 if (g_vbgldata.status == VbglStatusInitializing)
129 {
130 vbglQueryVMMDevPort ();
131 }
132#endif
133
134 rc = g_vbgldata.status == VbglStatusReady? VINF_SUCCESS: VERR_VBGL_NOT_INITIALIZED;
135
136 // dprintf(("VbglEnter: rc = %d\n", rc));
137
138 return rc;
139}
140
141int vbglInitCommon (void)
142{
143 int rc = VINF_SUCCESS;
144
145 RT_ZERO(g_vbgldata);
146
147 g_vbgldata.status = VbglStatusInitializing;
148
149 rc = VbglPhysHeapInit ();
150
151 if (RT_SUCCESS(rc))
152 {
153 /* other subsystems, none yet */
154 ;
155 }
156 else
157 LogRel(("vbglInitCommon: VbglPhysHeapInit failed. rc=%Rrc\n", rc));
158
159 dprintf(("vbglInitCommon: rc = %d\n", rc));
160
161 return rc;
162}
163
164DECLVBGL(void) vbglTerminateCommon (void)
165{
166 VbglPhysHeapTerminate ();
167
168 RT_ZERO(g_vbgldata);
169
170 return;
171}
172
173#ifdef VBGL_VBOXGUEST
174
175DECLVBGL(int) VbglInit (VBGLIOPORT portVMMDev, VMMDevMemory *pVMMDevMemory)
176{
177 int rc = VINF_SUCCESS;
178
179# ifdef RT_OS_WINDOWS /** @todo r=bird: this doesn't make sense. Is there something special going on on windows? */
180 dprintf(("vbglInit: starts g_vbgldata.status %d\n", g_vbgldata.status));
181
182 if (g_vbgldata.status == VbglStatusInitializing
183 || g_vbgldata.status == VbglStatusReady)
184 {
185 /* Initialization is already in process. */
186 return rc;
187 }
188# else
189 dprintf(("vbglInit: starts\n"));
190# endif
191
192 rc = vbglInitCommon ();
193
194 if (RT_SUCCESS(rc))
195 {
196 g_vbgldata.portVMMDev = portVMMDev;
197 g_vbgldata.pVMMDevMemory = pVMMDevMemory;
198
199 g_vbgldata.status = VbglStatusReady;
200
201 vbglR0QueryHostVersion();
202 }
203 else
204 {
205 g_vbgldata.status = VbglStatusNotInitialized;
206 }
207
208 return rc;
209}
210
211DECLVBGL(void) VbglTerminate (void)
212{
213 vbglTerminateCommon ();
214
215 return;
216}
217
218
219#else /* !VBGL_VBOXGUEST */
220
221DECLVBGL(int) VbglInit (void)
222{
223 int rc = VINF_SUCCESS;
224
225 if (g_vbgldata.status == VbglStatusInitializing
226 || g_vbgldata.status == VbglStatusReady)
227 {
228 /* Initialization is already in process. */
229 return rc;
230 }
231
232 rc = vbglInitCommon ();
233
234 if (RT_SUCCESS(rc))
235 {
236 /* Try to obtain VMMDev port via IOCTL to VBoxGuest main driver. */
237 vbglQueryVMMDevPort ();
238
239# ifdef VBOX_WITH_HGCM
240 rc = vbglR0HGCMInit ();
241# endif /* VBOX_WITH_HGCM */
242
243 if (RT_FAILURE(rc))
244 {
245 vbglTerminateCommon ();
246 }
247 }
248
249 return rc;
250}
251
252DECLVBGL(void) VbglTerminate (void)
253{
254# ifdef VBOX_WITH_HGCM
255 vbglR0HGCMTerminate ();
256# endif
257
258 vbglTerminateCommon ();
259
260 return;
261}
262
263#endif /* !VBGL_VBOXGUEST */
264
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