VirtualBox

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

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

Started solaris additions and the os2 to common move.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.8 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 (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#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#ifdef RT_OS_SOLARIS
135__BEGIN_DECLS
136extern DECLVBGL(void *) VBoxGuestSolarisServiceOpen (uint32_t *pu32Version);
137extern DECLVBGL(void) VBoxGuestSolarisServiceClose (void *pvOpaque);
138extern DECLVBGL(int) VBoxGuestSolarisServiceCall (void *pvOpaque, unsigned int iCmd, void *pvData, size_t cbSize, size_t *pcbReturn);
139__END_DECLS
140#endif
141
142int vbglDriverOpen (VBGLDRIVER *pDriver)
143{
144#ifdef RT_OS_WINDOWS
145 UNICODE_STRING uszDeviceName;
146 RtlInitUnicodeString (&uszDeviceName, L"\\Device\\VBoxGuest");
147
148 PDEVICE_OBJECT pDeviceObject = NULL;
149 PFILE_OBJECT pFileObject = NULL;
150
151 NTSTATUS rc = IoGetDeviceObjectPointer (&uszDeviceName, FILE_ALL_ACCESS,
152 &pFileObject, &pDeviceObject);
153
154 if (NT_SUCCESS (rc))
155 {
156 Log(("vbglDriverOpen VBoxGuest successful pDeviceObject=%x\n", pDeviceObject));
157 pDriver->pDeviceObject = pDeviceObject;
158 pDriver->pFileObject = pFileObject;
159 return VINF_SUCCESS;
160 }
161 /** @todo return RTErrConvertFromNtStatus(rc)! */
162 Log(("vbglDriverOpen VBoxGuest failed with ntstatus=%x\n", rc));
163 return rc;
164
165#elif defined (RT_OS_LINUX)
166 void *opaque;
167
168 opaque = (void *) vboxadd_cmc_open ();
169 if (!opaque)
170 {
171 return VERR_NOT_IMPLEMENTED;
172 }
173 pDriver->opaque = opaque;
174 return VINF_SUCCESS;
175
176#elif defined (RT_OS_OS2)
177 /*
178 * Just check whether the connection was made or not.
179 */
180 if ( g_VBoxGuestIDC.u32Version == VMMDEV_VERSION
181 && VALID_PTR(g_VBoxGuestIDC.u32Session)
182 && VALID_PTR(g_VBoxGuestIDC.pfnServiceEP))
183 {
184 pDriver->u32Session = g_VBoxGuestIDC.u32Session;
185 return VINF_SUCCESS;
186 }
187 pDriver->u32Session = UINT32_MAX;
188 Log(("vbglDriverOpen: failed\n"));
189 return VERR_FILE_NOT_FOUND;
190
191#elif defined (RT_OS_SOLARIS)
192 uint32_t u32VMMDevVersion;
193 pDriver->pvOpaque = VBoxGuestSolarisServiceOpen(&u32VMMDevVersion);
194 if ( pDriver->pvOpaque
195 && u32VMMDevVersion == VMMDEV_VERSION)
196 return VINF_SUCCESS;
197
198 Log(("vbglDriverOpen: failed\n"));
199 return VERR_FILE_NOT_FOUND;
200
201#else
202# error "Port me"
203#endif
204}
205
206int vbglDriverIOCtl (VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData)
207{
208#ifdef RT_OS_WINDOWS
209 IO_STATUS_BLOCK ioStatusBlock;
210
211 KEVENT Event;
212 KeInitializeEvent (&Event, NotificationEvent, FALSE);
213
214 PIRP irp = IoBuildDeviceIoControlRequest (u32Function,
215 pDriver->pDeviceObject,
216 pvData,
217 cbData,
218 pvData,
219 cbData,
220 FALSE, /* external */
221 &Event,
222 &ioStatusBlock);
223 if (irp == NULL)
224 {
225 Log(("vbglDriverIOCtl: IoBuildDeviceIoControlRequest failed\n"));
226 return VERR_NO_MEMORY;
227 }
228
229 NTSTATUS rc = IoCallDriver (pDriver->pDeviceObject, irp);
230
231 if (rc == STATUS_PENDING)
232 {
233 Log(("vbglDriverIOCtl: STATUS_PENDING\n"));
234 rc = KeWaitForSingleObject(&Event,
235 Executive,
236 KernelMode,
237 FALSE,
238 NULL);
239
240 rc = ioStatusBlock.Status;
241 }
242
243 if (!NT_SUCCESS(rc))
244 Log(("vbglDriverIOCtl: IoCallDriver failed with ntstatus=%x\n", rc));
245
246 return NT_SUCCESS(rc)? VINF_SUCCESS: VERR_VBGL_IOCTL_FAILED;
247
248#elif defined (RT_OS_LINUX)
249 return vboxadd_cmc_call (pDriver->opaque, u32Function, pvData);
250
251#elif defined (RT_OS_OS2)
252 if ( pDriver->u32Session
253 && pDriver->u32Session == g_VBoxGuestIDC.u32Session)
254 return g_VBoxGuestIDC.pfnServiceEP(pDriver->u32Session, u32Function, pvData, cbData, NULL);
255
256 Log(("vbglDriverIOCtl: No connection\n"));
257 return VERR_WRONG_ORDER;
258
259#elif defined (RT_OS_SOLARIS)
260 return VBoxGuestSolarisServiceCall(pDriver->pvOpaque, u32Function, pvData, cbData, NULL);
261
262#else
263# error "Port me"
264#endif
265}
266
267void vbglDriverClose (VBGLDRIVER *pDriver)
268{
269#ifdef RT_OS_WINDOWS
270 Log(("vbglDriverClose pDeviceObject=%x\n", pDriver->pDeviceObject));
271 ObDereferenceObject (pDriver->pFileObject);
272
273#elif defined (RT_OS_LINUX)
274 vboxadd_cmc_close (pDriver->opaque);
275
276#elif defined (RT_OS_OS2)
277 pDriver->u32Session = 0;
278
279#elif defined (RT_OS_SOLARIS)
280 VBoxGuestSolarisServiceClose (pDriver->pvOpaque);
281
282#else
283# error "Port me"
284#endif
285}
286
287#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