VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp@ 8155

Last change on this file since 8155 was 8155, checked in by vboxsync, 17 years ago

The Big Sun Rebranding Header Change

  • Property svn:eol-style set to native
  • Property svn:keyword set to Id
  • Property svn:keywords set to Id
File size: 8.2 KB
Line 
1/* $Id: VBoxGuestR3Lib.cpp 8155 2008-04-18 15:16:47Z vboxsync $ */
2/** @file
3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Core.
4 */
5
6/*
7 * Copyright (C) 2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. 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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#ifdef RT_OS_OS2
27# define INCL_BASE
28# define INCL_ERRORS
29# include <os2.h>
30#elif defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
31# include <sys/types.h>
32# include <sys/stat.h>
33# include <errno.h>
34# include <unistd.h>
35#endif
36
37#include <iprt/time.h>
38#include <iprt/asm.h>
39#include <iprt/string.h>
40#include <iprt/file.h>
41#include <iprt/assert.h>
42#include <iprt/thread.h>
43#include <VBox/VBoxGuest.h>
44#include <VBox/log.h>
45#include "VBGLR3Internal.h"
46
47#ifdef VBOX_VBGLR3_XFREE86
48/* Rather than try to resolve all the header file conflicts, I will just
49 prototype what we need here. */
50# define XF86_O_RDWR 0x0002
51typedef void *pointer;
52extern "C" int xf86open(const char*, int,...);
53extern "C" int xf86close(int);
54extern "C" int xf86ioctl(int, unsigned long, pointer);
55#endif
56
57/*******************************************************************************
58* Global Variables *
59*******************************************************************************/
60/** The VBoxGuest device handle. */
61#ifdef VBOX_VBGLR3_XFREE86
62static int g_File = -1;
63#else
64static RTFILE g_File = NIL_RTFILE;
65#endif
66/** User counter.
67 * A counter of the number of times the library has been initialised, for use with
68 * X.org drivers, where the library may be shared by multiple independant modules
69 * inside a single process space.
70 */
71static uint32_t volatile g_cInits = 0;
72
73
74VBGLR3DECL(int) VbglR3Init(void)
75{
76 uint32_t cInits = ASMAtomicIncU32(&g_cInits);
77#ifndef VBOX_VBGLR3_XFREE86
78 Assert(cInits > 0);
79#endif
80 if (cInits > 1)
81 {
82 /*
83 * This will fail if two (or more) threads race each other calling VbglR3Init.
84 * However it will work fine for single threaded or otherwise serialized
85 * processed calling us more than once.
86 */
87#ifndef VBOX_VBGLR3_XFREE86
88 if (g_File == NIL_RTFILE)
89#else
90 if (g_File == -1)
91#endif
92 return VERR_INTERNAL_ERROR;
93 return VINF_SUCCESS;
94 }
95#ifndef VBOX_VBGLR3_XFREE86
96 if (g_File != NIL_RTFILE)
97#else
98 if (g_File != -1)
99#endif
100 return VERR_INTERNAL_ERROR;
101
102#if defined(RT_OS_OS2)
103 /*
104 * We might wish to compile this with Watcom, so stick to
105 * the OS/2 APIs all the way. And in any case we have to use
106 * DosDevIOCtl for the requests, why not use Dos* for everything.
107 */
108 HFILE hf = NULLHANDLE;
109 ULONG ulAction = 0;
110 APIRET rc = DosOpen((PCSZ)VBOXGUEST_DEVICE_NAME, &hf, &ulAction, 0, FILE_NORMAL,
111 OPEN_ACTION_OPEN_IF_EXISTS,
112 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
113 NULL);
114 if (rc)
115 return RTErrConvertFromOS2(rc);
116
117 if (hf < 16)
118 {
119 HFILE ahfs[16];
120 unsigned i;
121 for (i = 0; i < RT_ELEMENTS(ahfs); i++)
122 {
123 ahfs[i] = 0xffffffff;
124 rc = DosDupHandle(hf, &ahfs[i]);
125 if (rc)
126 break;
127 }
128
129 if (i-- > 1)
130 {
131 ULONG fulState = 0;
132 rc = DosQueryFHState(ahfs[i], &fulState);
133 if (!rc)
134 {
135 fulState |= OPEN_FLAGS_NOINHERIT;
136 fulState &= OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT; /* Turn off non-participating bits. */
137 rc = DosSetFHState(ahfs[i], fulState);
138 }
139 if (!rc)
140 {
141 rc = DosClose(hf);
142 AssertMsg(!rc, ("%ld\n", rc));
143 hf = ahfs[i];
144 }
145 else
146 i++;
147 while (i-- > 0)
148 DosClose(ahfs[i]);
149 }
150 }
151 g_File = hf;
152
153#elif defined(VBOX_VBGLR3_XFREE86)
154 int File = xf86open(VBOXGUEST_DEVICE_NAME, XF86_O_RDWR);
155 if (File == -1)
156 return VERR_OPEN_FAILED;
157 g_File = File;
158
159#else
160 /* the default implemenation. (linux, solaris) */
161 RTFILE File;
162 int rc = RTFileOpen(&File, VBOXGUEST_DEVICE_NAME, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
163 if (RT_FAILURE(rc))
164 return rc;
165 g_File = File;
166
167#endif
168
169 /* Create release logger */
170 PRTLOGGER loggerRelease;
171 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
172 int rrc = RTLogCreate(&loggerRelease, 0, NULL, "VBOXGUEST_RELEASE_LOG",
173 RT_ELEMENTS(s_apszGroups), &s_apszGroups[0],
174 RTLOGDEST_USER, "VBox.log");
175 /* This may legitimately fail if we are using the mini-runtime. */
176 if (RT_SUCCESS(rrc))
177 RTLogRelSetDefaultInstance(loggerRelease);
178
179 return VINF_SUCCESS;
180}
181
182
183VBGLR3DECL(void) VbglR3Term(void)
184{
185 uint32_t cInits = ASMAtomicDecU32(&g_cInits);
186 if (cInits > 0)
187 return;
188#ifndef VBOX_VBGLR3_XFREE86
189 AssertReturnVoid(!cInits);
190 RTFILE File = g_File;
191 g_File = NIL_RTFILE;
192 AssertReturnVoid(File != NIL_RTFILE);
193
194#else
195 int File = g_File;
196 g_File = -1;
197 if (File == -1)
198 return;
199#endif
200
201#if defined(RT_OS_OS2)
202 APIRET rc = DosClose(File);
203 AssertMsg(!rc, ("%ld\n", rc));
204
205#elif defined(VBOX_VBGLR3_XFREE86)
206 xf86close(File);
207 File = -1;
208
209#else
210 int rc = RTFileClose(File);
211 AssertRC(rc);
212#endif
213}
214
215
216/**
217 * Internal wrapper around various OS specific ioctl implemenations.
218 *
219 * @returns VBox status code as returned by VBoxGuestCommonIOCtl, or
220 * an failure returned by the OS specific ioctl APIs.
221 *
222 * @param iFunction The requested function.
223 * @param pvData The input and output data buffer.
224 * @param cbData The size of the buffer.
225 *
226 * @remark Exactly how the VBoxGuestCommonIOCtl is ferried back
227 * here is OS specific. On BSD and Darwin we can use errno,
228 * while on OS/2 we use the 2nd buffer of the IOCtl.
229 */
230int vbglR3DoIOCtl(unsigned iFunction, void *pvData, size_t cbData)
231{
232#ifdef RT_OS_OS2
233 ULONG cbOS2Parm = cbData;
234 int32_t vrc = VERR_INTERNAL_ERROR;
235 ULONG cbOS2Data = sizeof(vrc);
236 APIRET rc = DosDevIOCtl(g_File, VBOXGUEST_IOCTL_CATEGORY, iFunction,
237 pvData, cbData, &cbOS2Parm,
238 &vrc, sizeof(vrc), &cbOS2Data);
239 if (RT_LIKELY(!rc))
240 return vrc;
241 return RTErrConvertFromOS2(rc);
242
243#elif defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
244 VBGLBIGREQ Hdr;
245 Hdr.u32Magic = VBGLBIGREQ_MAGIC;
246 Hdr.cbData = cbData;
247 Hdr.pvDataR3 = pvData;
248
249/** @todo test status code passing! */
250 int rc = ioctl((int)g_File, iFunction, &Hdr);
251 if (rc == -1)
252 {
253 rc = errno;
254 return RTErrConvertFromErrno(rc);
255 }
256 return VINF_SUCCESS;
257
258#elif defined(VBOX_VBGLR3_XFREE86)
259 /* PORTME - This is preferred over the RTFileIOCtl variant below, just be careful with the (int). */
260/** @todo test status code passing! */
261 int rc = xf86ioctl(g_File, iFunction, pvData);
262 if (rc == -1)
263 return VERR_FILE_IO_ERROR; /* This is purely legacy stuff, it has to work and no more. */
264 return VINF_SUCCESS;
265
266#else
267 /* Default implementation - PORTME: Do not use this without testings that passing errors works! */
268/** @todo test status code passing! */
269 int rc2 = VERR_INTERNAL_ERROR;
270 int rc = RTFileIoCtl(g_File, (int)iFunction, pvData, cbData, &rc2);
271 if (RT_SUCCESS(rc))
272 rc = rc2;
273 return rc;
274#endif
275}
276
Note: See TracBrowser for help on using the repository browser.

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