VirtualBox

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

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

RTR0MemGetAddressR3 & RTR0MemObjLockUser. Linux memobj impl.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 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 innotek GmbH
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 as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18#define LOG_GROUP LOG_GROUP_HGCM
19#include <VBox/log.h>
20
21#include <VBox/VBoxGuestLib.h>
22#include "SysHlp.h"
23
24#include <iprt/assert.h>
25#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_LINUX)
26#include <iprt/memobj.h>
27#endif
28
29
30int vbglLockLinear (void **ppvCtx, void *pv, uint32_t u32Size, bool fWriteAccess)
31{
32 int rc = VINF_SUCCESS;
33
34#ifdef RT_OS_WINDOWS
35 PMDL pMdl = IoAllocateMdl (pv, u32Size, FALSE, FALSE, NULL);
36
37 if (pMdl == NULL)
38 {
39 rc = VERR_NOT_SUPPORTED;
40 AssertMsgFailed(("IoAllocateMdl %VGv %x failed!!\n", pv, u32Size));
41 }
42 else
43 {
44 __try {
45 /* Calls to MmProbeAndLockPages must be enclosed in a try/except block. */
46 MmProbeAndLockPages (pMdl,
47 KernelMode,
48 (fWriteAccess) ? IoModifyAccess : IoReadAccess);
49
50 *ppvCtx = pMdl;
51
52 } __except(EXCEPTION_EXECUTE_HANDLER) {
53
54 IoFreeMdl (pMdl);
55 rc = VERR_INVALID_PARAMETER;
56 AssertMsgFailed(("MmProbeAndLockPages %VGv %x failed!!\n", pv, u32Size));
57 }
58 }
59
60#elif defined(RT_OS_LINUX)
61 NOREF(ppvCtx);
62 NOREF(pv);
63 NOREF(u32Size);
64
65#else
66 /* Default to IPRT - this ASSUMES that it is USER addresses we're locking. */
67 RTR0MEMOBJ MemObj;
68 rc = RTR0MemObjLockUser(&MemObj, (RTR3PTR)pv, u32Size, NIL_RTR0PROCESS);
69 if (RT_SUCCESS(rc))
70 *ppvCtx = MemObj;
71 else
72 *ppvCtx = NIL_RTR0MEMOBJ;
73
74#endif
75
76 return rc;
77}
78
79void vbglUnlockLinear (void *pvCtx, void *pv, uint32_t u32Size)
80{
81 NOREF(pv);
82 NOREF(u32Size);
83
84#ifdef RT_OS_WINDOWS
85 PMDL pMdl = (PMDL)pvCtx;
86
87 Assert(pMdl);
88 if (pMdl != NULL)
89 {
90 MmUnlockPages (pMdl);
91 IoFreeMdl (pMdl);
92 }
93
94#elif defined(RT_OS_LINUX)
95 NOREF(pvCtx);
96
97#else
98 /* default to IPRT */
99 RTR0MEMOBJ MemObj = (RTR0MEMOBJ)pvCtx;
100 int rc = RTR0MemObjFree(MemObj, false);
101 AssertRC(rc);
102
103#endif
104}
105
106#ifndef VBGL_VBOXGUEST
107
108#if defined (RT_OS_LINUX) && !defined (__KERNEL__)
109# include <unistd.h>
110# include <errno.h>
111# include <sys/fcntl.h>
112# include <sys/ioctl.h>
113#endif
114
115#ifdef RT_OS_LINUX
116__BEGIN_DECLS
117extern DECLVBGL(void *) vboxadd_cmc_open (void);
118extern DECLVBGL(void) vboxadd_cmc_close (void *);
119extern DECLVBGL(int) vboxadd_cmc_call (void *opaque, uint32_t func, void *data);
120__END_DECLS
121#endif /* RT_OS_LINUX */
122
123#ifdef RT_OS_OS2
124__BEGIN_DECLS
125/*
126 * On OS/2 we'll do the connecting in the assembly code of the
127 * client driver, exporting a g_VBoxGuestIDC symbol containing
128 * the connection information obtained from the 16-bit IDC.
129 */
130extern VBOXGUESTOS2IDCCONNECT g_VBoxGuestIDC;
131__END_DECLS
132#endif
133
134
135int vbglDriverOpen (VBGLDRIVER *pDriver)
136{
137#ifdef RT_OS_WINDOWS
138 UNICODE_STRING uszDeviceName;
139 RtlInitUnicodeString (&uszDeviceName, L"\\Device\\VBoxGuest");
140
141 PDEVICE_OBJECT pDeviceObject = NULL;
142 PFILE_OBJECT pFileObject = NULL;
143
144 NTSTATUS rc = IoGetDeviceObjectPointer (&uszDeviceName, FILE_ALL_ACCESS,
145 &pFileObject, &pDeviceObject);
146
147 if (NT_SUCCESS (rc))
148 {
149 Log(("vbglDriverOpen VBoxGuest successful pDeviceObject=%x\n", pDeviceObject));
150 pDriver->pDeviceObject = pDeviceObject;
151 pDriver->pFileObject = pFileObject;
152 return VINF_SUCCESS;
153 }
154 /** @todo return RTErrConvertFromNtStatus(rc)! */
155 Log(("vbglDriverOpen VBoxGuest failed with ntstatus=%x\n", rc));
156 return rc;
157
158#elif defined (RT_OS_LINUX)
159 void *opaque;
160
161 opaque = (void *) vboxadd_cmc_open ();
162 if (!opaque)
163 {
164 return VERR_NOT_IMPLEMENTED;
165 }
166 pDriver->opaque = opaque;
167 return VINF_SUCCESS;
168
169#elif defined (RT_OS_OS2)
170 /*
171 * Just check whether the connection was made or not.
172 */
173 if ( g_VBoxGuestIDC.u32Version == VMMDEV_VERSION
174 && VALID_PTR(g_VBoxGuestIDC.u32Session)
175 && VALID_PTR(g_VBoxGuestIDC.pfnServiceEP))
176 {
177 pDriver->u32Session = g_VBoxGuestIDC.u32Session;
178 return VINF_SUCCESS;
179 }
180 pDriver->u32Session = UINT32_MAX;
181 Log(("vbglDriverOpen: failed\n"));
182 return VERR_FILE_NOT_FOUND;
183
184#else
185# error "Port me"
186#endif
187}
188
189int vbglDriverIOCtl (VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData)
190{
191#ifdef RT_OS_WINDOWS
192 IO_STATUS_BLOCK ioStatusBlock;
193
194 KEVENT Event;
195 KeInitializeEvent (&Event, NotificationEvent, FALSE);
196
197 PIRP irp = IoBuildDeviceIoControlRequest (u32Function,
198 pDriver->pDeviceObject,
199 pvData,
200 cbData,
201 pvData,
202 cbData,
203 FALSE, /* external */
204 &Event,
205 &ioStatusBlock);
206 if (irp == NULL)
207 {
208 Log(("vbglDriverIOCtl: IoBuildDeviceIoControlRequest failed\n"));
209 return VERR_NO_MEMORY;
210 }
211
212 NTSTATUS rc = IoCallDriver (pDriver->pDeviceObject, irp);
213
214 if (rc == STATUS_PENDING)
215 {
216 Log(("vbglDriverIOCtl: STATUS_PENDING\n"));
217 rc = KeWaitForSingleObject(&Event,
218 Executive,
219 KernelMode,
220 FALSE,
221 NULL);
222
223 rc = ioStatusBlock.Status;
224 }
225
226 if (!NT_SUCCESS(rc))
227 Log(("vbglDriverIOCtl: IoCallDriver failed with ntstatus=%x\n", rc));
228
229 return NT_SUCCESS(rc)? VINF_SUCCESS: VERR_VBGL_IOCTL_FAILED;
230
231#elif defined (RT_OS_LINUX)
232 return vboxadd_cmc_call (pDriver->opaque, u32Function, pvData);
233
234#elif defined (RT_OS_OS2)
235 if ( pDriver->u32Session
236 && pDriver->u32Session == g_VBoxGuestIDC.u32Session)
237 return g_VBoxGuestIDC.pfnServiceEP(pDriver->u32Session, u32Function, pvData, cbData, NULL);
238
239 Log(("vbglDriverIOCtl: No connection\n"));
240 return VERR_WRONG_ORDER;
241
242#else
243# error "Port me"
244#endif
245}
246
247void vbglDriverClose (VBGLDRIVER *pDriver)
248{
249#ifdef RT_OS_WINDOWS
250 Log(("vbglDriverClose pDeviceObject=%x\n", pDriver->pDeviceObject));
251 ObDereferenceObject (pDriver->pFileObject);
252
253#elif defined (RT_OS_LINUX)
254 vboxadd_cmc_close (pDriver->opaque);
255
256#elif defined (RT_OS_OS2)
257 pDriver->u32Session = 0;
258
259#else
260# error "Port me"
261#endif
262}
263
264#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