VirtualBox

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

Last change on this file since 10797 was 10079, checked in by vboxsync, 16 years ago

Logging.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.3 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 Log(("vbglDriverIOCtl: pDriver: %p, Func: %d, pvData: %p, cbData: %d\n", pDriver, u32Function, pvData, cbData));
232
233#ifdef RT_OS_WINDOWS
234 IO_STATUS_BLOCK ioStatusBlock;
235
236 KEVENT Event;
237 KeInitializeEvent (&Event, NotificationEvent, FALSE);
238
239 PIRP irp = IoBuildDeviceIoControlRequest (u32Function,
240 pDriver->pDeviceObject,
241 pvData,
242 cbData,
243 pvData,
244 cbData,
245 FALSE, /* external */
246 &Event,
247 &ioStatusBlock);
248 if (irp == NULL)
249 {
250 Log(("vbglDriverIOCtl: IoBuildDeviceIoControlRequest failed!\n"));
251 return VERR_NO_MEMORY;
252 }
253
254 NTSTATUS rc = IoCallDriver (pDriver->pDeviceObject, irp);
255
256 if (rc == STATUS_PENDING)
257 {
258 Log(("vbglDriverIOCtl: STATUS_PENDING\n"));
259 rc = KeWaitForSingleObject(&Event,
260 Executive,
261 KernelMode,
262 FALSE,
263 NULL);
264
265 rc = ioStatusBlock.Status;
266 }
267
268 if (!NT_SUCCESS(rc))
269 Log(("vbglDriverIOCtl: IoCallDriver failed with ntstatus=%x\n", rc));
270
271 return NT_SUCCESS(rc)? VINF_SUCCESS: VERR_VBGL_IOCTL_FAILED;
272
273#elif defined (RT_OS_LINUX)
274 return vboxadd_cmc_call (pDriver->opaque, u32Function, pvData);
275
276#elif defined (RT_OS_OS2)
277 if ( pDriver->u32Session
278 && pDriver->u32Session == g_VBoxGuestIDC.u32Session)
279 return g_VBoxGuestIDC.pfnServiceEP(pDriver->u32Session, u32Function, pvData, cbData, NULL);
280
281 Log(("vbglDriverIOCtl: No connection\n"));
282 return VERR_WRONG_ORDER;
283
284#elif defined (RT_OS_SOLARIS)
285 return VBoxGuestSolarisServiceCall(pDriver->pvOpaque, u32Function, pvData, cbData, NULL);
286
287#elif defined (RT_OS_FREEBSD)
288 return VBoxGuestFreeBSDServiceCall(pDriver->pvOpaque, u32Function, pvData, cbData, NULL);
289
290#else
291# error "Port me"
292#endif
293}
294
295void vbglDriverClose (VBGLDRIVER *pDriver)
296{
297#ifdef RT_OS_WINDOWS
298 Log(("vbglDriverClose pDeviceObject=%x\n", pDriver->pDeviceObject));
299 ObDereferenceObject (pDriver->pFileObject);
300
301#elif defined (RT_OS_LINUX)
302 vboxadd_cmc_close (pDriver->opaque);
303
304#elif defined (RT_OS_OS2)
305 pDriver->u32Session = 0;
306
307#elif defined (RT_OS_SOLARIS)
308 VBoxGuestSolarisServiceClose (pDriver->pvOpaque);
309
310#elif defined (RT_OS_FREEBSD)
311 VBoxGuestFreeBSDServiceClose(pDriver->pvOpaque);
312
313#else
314# error "Port me"
315#endif
316}
317
318#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