VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuestLib/SysHlp.cpp@ 9292

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

The Big Sun Rebranding Header Change

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1/** @file
2 *
3 * VBoxGuestLib - A support library for VirtualBox guest additions:
4 * Physical memory heap
5 */
6
7/*
8 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22#define LOG_GROUP LOG_GROUP_HGCM
23#include <VBox/log.h>
24
25#include <VBox/VBoxGuestLib.h>
26#include "SysHlp.h"
27
28#include <iprt/assert.h>
29#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_LINUX)
30#include <iprt/memobj.h>
31#endif
32
33
34int vbglLockLinear (void **ppvCtx, void *pv, uint32_t u32Size, bool fWriteAccess)
35{
36 int rc = VINF_SUCCESS;
37
38#ifdef RT_OS_WINDOWS
39 PMDL pMdl = IoAllocateMdl (pv, u32Size, FALSE, FALSE, NULL);
40
41 if (pMdl == NULL)
42 {
43 rc = VERR_NOT_SUPPORTED;
44 AssertMsgFailed(("IoAllocateMdl %VGv %x failed!!\n", pv, u32Size));
45 }
46 else
47 {
48 __try {
49 /* Calls to MmProbeAndLockPages must be enclosed in a try/except block. */
50 MmProbeAndLockPages (pMdl,
51 KernelMode,
52 (fWriteAccess) ? IoModifyAccess : IoReadAccess);
53
54 *ppvCtx = pMdl;
55
56 } __except(EXCEPTION_EXECUTE_HANDLER) {
57
58 IoFreeMdl (pMdl);
59 rc = VERR_INVALID_PARAMETER;
60 AssertMsgFailed(("MmProbeAndLockPages %VGv %x failed!!\n", pv, u32Size));
61 }
62 }
63
64#elif defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) /** @todo r=bird: I don't think FreeBSD shouldn't go here, solaris and OS/2 doesn't
65 * (ignore linux as it's not using the same ioctl code).
66 * That said, the assumption below might be wrong for in kernel calls... */
67 NOREF(ppvCtx);
68 NOREF(pv);
69 NOREF(u32Size);
70
71#else
72 /* Default to IPRT - this ASSUMES that it is USER addresses we're locking. */
73 RTR0MEMOBJ MemObj;
74 rc = RTR0MemObjLockUser(&MemObj, (RTR3PTR)pv, u32Size, NIL_RTR0PROCESS);
75 if (RT_SUCCESS(rc))
76 *ppvCtx = MemObj;
77 else
78 *ppvCtx = NIL_RTR0MEMOBJ;
79
80#endif
81
82 return rc;
83}
84
85void vbglUnlockLinear (void *pvCtx, void *pv, uint32_t u32Size)
86{
87 NOREF(pv);
88 NOREF(u32Size);
89
90#ifdef RT_OS_WINDOWS
91 PMDL pMdl = (PMDL)pvCtx;
92
93 Assert(pMdl);
94 if (pMdl != NULL)
95 {
96 MmUnlockPages (pMdl);
97 IoFreeMdl (pMdl);
98 }
99
100#elif defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
101 NOREF(pvCtx);
102
103#else
104 /* default to IPRT */
105 RTR0MEMOBJ MemObj = (RTR0MEMOBJ)pvCtx;
106 int rc = RTR0MemObjFree(MemObj, false);
107 AssertRC(rc);
108
109#endif
110}
111
112#ifndef VBGL_VBOXGUEST
113
114#if defined (RT_OS_LINUX) && !defined (__KERNEL__)
115# include <unistd.h>
116# include <errno.h>
117# include <sys/fcntl.h>
118# include <sys/ioctl.h>
119#endif
120
121#ifdef RT_OS_LINUX
122__BEGIN_DECLS
123extern DECLVBGL(void *) vboxadd_cmc_open (void);
124extern DECLVBGL(void) vboxadd_cmc_close (void *);
125extern DECLVBGL(int) vboxadd_cmc_call (void *opaque, uint32_t func, void *data);
126__END_DECLS
127#endif /* RT_OS_LINUX */
128
129#ifdef RT_OS_OS2
130__BEGIN_DECLS
131/*
132 * On OS/2 we'll do the connecting in the assembly code of the
133 * client driver, exporting a g_VBoxGuestIDC symbol containing
134 * the connection information obtained from the 16-bit IDC.
135 */
136extern VBOXGUESTOS2IDCCONNECT g_VBoxGuestIDC;
137__END_DECLS
138#endif
139
140#ifdef RT_OS_SOLARIS
141__BEGIN_DECLS
142extern DECLVBGL(void *) VBoxGuestSolarisServiceOpen (uint32_t *pu32Version);
143extern DECLVBGL(void) VBoxGuestSolarisServiceClose (void *pvOpaque);
144extern DECLVBGL(int) VBoxGuestSolarisServiceCall (void *pvOpaque, unsigned int iCmd, void *pvData, size_t cbSize, size_t *pcbReturn);
145__END_DECLS
146
147#elif defined (RT_OS_FREEBSD)
148__BEGIN_DECLS
149extern DECLVBGL(void *) VBoxGuestFreeBSDServiceOpen (uint32_t *pu32Version);
150extern DECLVBGL(void) VBoxGuestFreeBSDServiceClose (void *pvOpaque);
151extern DECLVBGL(int) VBoxGuestFreeBSDServiceCall (void *pvOpaque, unsigned int iCmd, void *pvData, size_t cbSize, size_t *pcbReturn);
152__END_DECLS
153
154#endif
155
156int vbglDriverOpen (VBGLDRIVER *pDriver)
157{
158#ifdef RT_OS_WINDOWS
159 UNICODE_STRING uszDeviceName;
160 RtlInitUnicodeString (&uszDeviceName, L"\\Device\\VBoxGuest");
161
162 PDEVICE_OBJECT pDeviceObject = NULL;
163 PFILE_OBJECT pFileObject = NULL;
164
165 NTSTATUS rc = IoGetDeviceObjectPointer (&uszDeviceName, FILE_ALL_ACCESS,
166 &pFileObject, &pDeviceObject);
167
168 if (NT_SUCCESS (rc))
169 {
170 Log(("vbglDriverOpen VBoxGuest successful pDeviceObject=%x\n", pDeviceObject));
171 pDriver->pDeviceObject = pDeviceObject;
172 pDriver->pFileObject = pFileObject;
173 return VINF_SUCCESS;
174 }
175 /** @todo return RTErrConvertFromNtStatus(rc)! */
176 Log(("vbglDriverOpen VBoxGuest failed with ntstatus=%x\n", rc));
177 return rc;
178
179#elif defined (RT_OS_LINUX)
180 void *opaque;
181
182 opaque = (void *) vboxadd_cmc_open ();
183 if (!opaque)
184 {
185 return VERR_NOT_IMPLEMENTED;
186 }
187 pDriver->opaque = opaque;
188 return VINF_SUCCESS;
189
190#elif defined (RT_OS_OS2)
191 /*
192 * Just check whether the connection was made or not.
193 */
194 if ( g_VBoxGuestIDC.u32Version == VMMDEV_VERSION
195 && VALID_PTR(g_VBoxGuestIDC.u32Session)
196 && VALID_PTR(g_VBoxGuestIDC.pfnServiceEP))
197 {
198 pDriver->u32Session = g_VBoxGuestIDC.u32Session;
199 return VINF_SUCCESS;
200 }
201 pDriver->u32Session = UINT32_MAX;
202 Log(("vbglDriverOpen: failed\n"));
203 return VERR_FILE_NOT_FOUND;
204
205#elif defined (RT_OS_SOLARIS)
206 uint32_t u32VMMDevVersion;
207 pDriver->pvOpaque = VBoxGuestSolarisServiceOpen(&u32VMMDevVersion);
208 if ( pDriver->pvOpaque
209 && u32VMMDevVersion == VMMDEV_VERSION)
210 return VINF_SUCCESS;
211
212 Log(("vbglDriverOpen: failed\n"));
213 return VERR_FILE_NOT_FOUND;
214
215#elif defined (RT_OS_FREEBSD)
216 uint32_t u32VMMDevVersion;
217 pDriver->pvOpaque = VBoxGuestFreeBSDServiceOpen(&u32VMMDevVersion);
218 if (pDriver->pvOpaque && (u32VMMDevVersion == VMMDEV_VERSION))
219 return VINF_SUCCESS;
220
221 Log(("vbglDriverOpen: failed\n"));
222 return VERR_FILE_NOT_FOUND;
223
224#else
225# error "Port me"
226#endif
227}
228
229int vbglDriverIOCtl (VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData)
230{
231#ifdef RT_OS_WINDOWS
232 IO_STATUS_BLOCK ioStatusBlock;
233
234 KEVENT Event;
235 KeInitializeEvent (&Event, NotificationEvent, FALSE);
236
237 PIRP irp = IoBuildDeviceIoControlRequest (u32Function,
238 pDriver->pDeviceObject,
239 pvData,
240 cbData,
241 pvData,
242 cbData,
243 FALSE, /* external */
244 &Event,
245 &ioStatusBlock);
246 if (irp == NULL)
247 {
248 Log(("vbglDriverIOCtl: IoBuildDeviceIoControlRequest failed\n"));
249 return VERR_NO_MEMORY;
250 }
251
252 NTSTATUS rc = IoCallDriver (pDriver->pDeviceObject, irp);
253
254 if (rc == STATUS_PENDING)
255 {
256 Log(("vbglDriverIOCtl: STATUS_PENDING\n"));
257 rc = KeWaitForSingleObject(&Event,
258 Executive,
259 KernelMode,
260 FALSE,
261 NULL);
262
263 rc = ioStatusBlock.Status;
264 }
265
266 if (!NT_SUCCESS(rc))
267 Log(("vbglDriverIOCtl: IoCallDriver failed with ntstatus=%x\n", rc));
268
269 return NT_SUCCESS(rc)? VINF_SUCCESS: VERR_VBGL_IOCTL_FAILED;
270
271#elif defined (RT_OS_LINUX)
272 return vboxadd_cmc_call (pDriver->opaque, u32Function, pvData);
273
274#elif defined (RT_OS_OS2)
275 if ( pDriver->u32Session
276 && pDriver->u32Session == g_VBoxGuestIDC.u32Session)
277 return g_VBoxGuestIDC.pfnServiceEP(pDriver->u32Session, u32Function, pvData, cbData, NULL);
278
279 Log(("vbglDriverIOCtl: No connection\n"));
280 return VERR_WRONG_ORDER;
281
282#elif defined (RT_OS_SOLARIS)
283 return VBoxGuestSolarisServiceCall(pDriver->pvOpaque, u32Function, pvData, cbData, NULL);
284
285#elif defined (RT_OS_FREEBSD)
286 return VBoxGuestFreeBSDServiceCall(pDriver->pvOpaque, u32Function, pvData, cbData, NULL);
287
288#else
289# error "Port me"
290#endif
291}
292
293void vbglDriverClose (VBGLDRIVER *pDriver)
294{
295#ifdef RT_OS_WINDOWS
296 Log(("vbglDriverClose pDeviceObject=%x\n", pDriver->pDeviceObject));
297 ObDereferenceObject (pDriver->pFileObject);
298
299#elif defined (RT_OS_LINUX)
300 vboxadd_cmc_close (pDriver->opaque);
301
302#elif defined (RT_OS_OS2)
303 pDriver->u32Session = 0;
304
305#elif defined (RT_OS_SOLARIS)
306 VBoxGuestSolarisServiceClose (pDriver->pvOpaque);
307
308#elif defined (RT_OS_FREEBSD)
309 VBoxGuestFreeBSDServiceClose(pDriver->pvOpaque);
310
311#else
312# error "Port me"
313#endif
314}
315
316#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