VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp@ 23837

Last change on this file since 23837 was 23837, checked in by vboxsync, 15 years ago

VBoxClient/VBoxTray/VBgl: More Windows bits.

  • Property svn:eol-style set to native
  • Property svn:keyword set to Id
  • Property svn:keywords set to Id
File size: 7.8 KB
Line 
1/* $Id: VBoxGuestR3LibMisc.cpp 23837 2009-10-16 22:54:47Z vboxsync $ */
2/** @file
3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Misc.
4 */
5
6/*
7 * Copyright (C) 2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#include <iprt/mem.h>
27#include <VBox/log.h>
28#include "VBGLR3Internal.h"
29
30
31/**
32 * Wait for the host to signal one or more events and return which.
33 *
34 * The events will only be delivered by the host if they have been enabled
35 * previously using @a VbglR3CtlFilterMask. If one or several of the events
36 * have already been signalled but not yet waited for, this function will return
37 * immediately and return those events.
38 *
39 * @returns IPRT status code
40 *
41 * @param fMask The events we want to wait for, or-ed together.
42 * @param cMillies How long to wait before giving up and returning
43 * (VERR_TIMEOUT). Use RT_INDEFINITE_WAIT to wait until we
44 * are interrupted or one of the events is signalled.
45 * @param pfEvents Where to store the events signalled. Optional.
46 */
47VBGLR3DECL(int) VbglR3WaitEvent(uint32_t fMask, uint32_t cMillies, uint32_t *pfEvents)
48{
49 LogFlow(("VbglR3WaitEvent: fMask=0x%x, cMillies=%u, pfEvents=%p\n",
50 fMask, cMillies, pfEvents));
51 AssertReturn((fMask & ~VMMDEV_EVENT_VALID_EVENT_MASK) == 0, VERR_INVALID_PARAMETER);
52 AssertPtrNullReturn(pfEvents, VERR_INVALID_POINTER);
53
54 VBoxGuestWaitEventInfo waitEvent;
55 waitEvent.u32TimeoutIn = cMillies;
56 waitEvent.u32EventMaskIn = fMask;
57 waitEvent.u32Result = VBOXGUEST_WAITEVENT_ERROR;
58 waitEvent.u32EventFlagsOut = 0;
59 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent));
60 if (RT_SUCCESS(rc))
61 {
62 AssertMsg(waitEvent.u32Result == VBOXGUEST_WAITEVENT_OK, ("%d\n", waitEvent.u32Result));
63 if (pfEvents)
64 *pfEvents = waitEvent.u32EventFlagsOut;
65 }
66
67 LogFlow(("VbglR3WaitEvent: rc=%Rrc, u32EventFlagsOut=0x%x. u32Result=%d\n",
68 rc, waitEvent.u32EventFlagsOut, waitEvent.u32Result));
69 return rc;
70}
71
72
73/**
74 * Cause any pending WaitEvent calls (VBOXGUEST_IOCTL_WAITEVENT) to return
75 * with a VERR_INTERRUPTED status.
76 *
77 * Can be used in combination with a termination flag variable for interrupting
78 * event loops. Avoiding race conditions is the responsibility of the caller.
79 *
80 * @returns IPRT status code
81 */
82VBGLR3DECL(int) VbglR3InterruptEventWaits(void)
83{
84 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS, 0, 0);
85}
86
87
88/**
89 * Write to the backdoor logger from ring 3 guest code.
90 *
91 * @returns IPRT status code
92 *
93 * @remarks This currently does not accept more than 255 bytes of data at
94 * one time. It should probably be rewritten to use pass a pointer
95 * in the IOCtl.
96 */
97VBGLR3DECL(int) VbglR3WriteLog(const char *pch, size_t cb)
98{
99 /*
100 * Quietly skip NULL strings.
101 * (Happens in the RTLogBackdoorPrintf case.)
102 */
103 if (!cb)
104 return VINF_SUCCESS;
105 if (!VALID_PTR(pch))
106 return VERR_INVALID_POINTER;
107
108#ifdef RT_OS_WINDOWS
109 /*
110 * Duplicate the string as it may be read only (a C string).
111 */
112 void *pvTmp = RTMemDup(pch, cb);
113 if (!pvTmp)
114 return VERR_NO_MEMORY;
115 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cb), pvTmp, cb);
116 RTMemFree(pvTmp);
117 return rc;
118
119#elif 0 /** @todo Several OSes could take this route (solaris and freebsd for instance). */
120 /*
121 * Handle the entire request in one go.
122 */
123 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cb), pvTmp, cb);
124
125#else
126 /*
127 * *BSD does not accept more than 4KB per ioctl request, while
128 * Linux can't express sizes above 8KB, so, split it up into 2KB chunks.
129 */
130# define STEP 2048
131 int rc = VINF_SUCCESS;
132 for (size_t off = 0; off < cb && RT_SUCCESS(rc); off += STEP)
133 {
134 size_t cbStep = RT_MIN(cb - off, STEP);
135 rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cbStep), (char *)pch + off, cbStep);
136 }
137# undef STEP
138 return rc;
139#endif
140}
141
142
143/**
144 * Change the IRQ filter mask.
145 *
146 * @returns IPRT status code
147 * @param fOr The OR mask.
148 * @param fNo The NOT mask.
149 */
150VBGLR3DECL(int) VbglR3CtlFilterMask(uint32_t fOr, uint32_t fNot)
151{
152#if defined(RT_OS_WINDOWS)
153 /** @todo Not yet implemented. */
154 return VERR_NOT_SUPPORTED;
155
156#else
157
158 VBoxGuestFilterMaskInfo Info;
159 Info.u32OrMask = fOr;
160 Info.u32NotMask = fNot;
161 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CTL_FILTER_MASK, &Info, sizeof(Info));
162#endif
163}
164
165
166/**
167 * Report a change in the capabilities that we support to the host.
168 *
169 * @returns IPRT status value
170 * @param fOr Capabilities which have been added.
171 * @param fNot Capabilities which have been removed.
172 *
173 * @todo Move to a different file.
174 */
175VBGLR3DECL(int) VbglR3SetGuestCaps(uint32_t fOr, uint32_t fNot)
176{
177 VMMDevReqGuestCapabilities2 vmmreqGuestCaps;
178 int rc;
179
180 vmmdevInitRequest(&vmmreqGuestCaps.header, VMMDevReq_SetGuestCapabilities);
181 vmmreqGuestCaps.u32OrMask = fOr;
182 vmmreqGuestCaps.u32NotMask = fNot;
183 rc = vbglR3GRPerform(&vmmreqGuestCaps.header);
184#ifdef DEBUG
185 if (RT_SUCCESS(rc))
186 LogRel(("Successfully changed guest capabilities: or mask 0x%x, not mask 0x%x.\n",
187 fOr, fNot));
188 else
189 LogRel(("Failed to change guest capabilities: or mask 0x%x, not mask 0x%x. rc = %Rrc.\n",
190 fOr, fNot, rc));
191#endif
192 return rc;
193}
194
195
196/** @todo Docs */
197VBGLR3DECL(int) VbglR3GetAdditionsVersion(char **ppszVer, char **ppszRev)
198{
199 int rc;
200#ifdef RT_OS_WINDOWS
201 HKEY hKey;
202 LONG r;
203
204 /* Check the new path first. */
205 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Sun\\VirtualBox Guest Additions", 0, KEY_READ, &hKey);
206#ifdef RT_ARCH_AMD64
207 if (r != ERROR_SUCCESS)
208 {
209 /* Check Wow6432Node (for new entries). */
210 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Sun\\VirtualBox Guest Additions", 0, KEY_READ, &hKey);
211 }
212#endif
213
214 /* Still no luck? Then try the old xVM paths ... */
215 if (FAILED(r))
216 {
217 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Sun\\xVM VirtualBox Guest Additions", 0, KEY_READ, &hKey);
218#ifdef RT_ARCH_AMD64
219 if (r != ERROR_SUCCESS)
220 {
221 /* Check Wow6432Node (for new entries). */
222 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Sun\\xVM VirtualBox Guest Additions", 0, KEY_READ, &hKey);
223 }
224#endif
225 }
226
227 /* Did we get something worth looking at? */
228 if (SUCCEEDED(r))
229 {
230 /* Version. */
231 DWORD dwType;
232 DWORD dwSize = 32;
233 char *pszVer = (char*)RTMemAlloc(dwSize);
234 if (pszVer)
235 {
236 if (ERROR_SUCCESS == RegQueryValueEx(hKey, "Version", NULL, &dwType, (BYTE*)(LPCTSTR)pszVer, &dwSize))
237 ppszVer = pszVer;
238 }
239 /* Revision. */
240 if (ppszRev)
241 {
242 dwSize = 32;
243 char pszRev = (char*)RTMemAlloc(dwSize);
244 if (ERROR_SUCCESS == RegQueryValueEx(hKey, "Revision", NULL, &dwType, (BYTE*)(LPCTSTR)pszRev, &dwSize))
245 ppszRev = pszRev;
246 }
247 }
248 rc = RTErrConvertFromWin32(r);
249
250 if (NULL != hKey)
251 RegCloseKey(hKey);
252#else
253#endif /* RT_OS_WINDOWS */
254 return rc;
255}
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