VirtualBox

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

Last change on this file since 3307 was 3306, checked in by vboxsync, 18 years ago

Added a IPRT base fallback implementation for locking and completed the OS/2 client code.

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