VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp@ 29608

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

VMMDevReq_RegisterSharedModule has a variable packet size as well

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.2 KB
Line 
1/* $Revision: 29360 $ */
2/** @file
3 * VBoxGuestLibR0 - Generic VMMDev request management.
4 */
5
6/*
7 * Copyright (C) 2006-2009 Oracle Corporation
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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27#include "VBGLInternal.h"
28#include <iprt/asm.h>
29#include <iprt/asm-amd64-x86.h>
30#include <iprt/assert.h>
31#include <iprt/string.h>
32
33DECLVBGL(int) VbglGRVerify (const VMMDevRequestHeader *pReq, size_t cbReq)
34{
35 if (!pReq || cbReq < sizeof (VMMDevRequestHeader))
36 {
37 dprintf(("VbglGRVerify: Invalid parameter: pReq = %p, cbReq = %d\n", pReq, cbReq));
38 return VERR_INVALID_PARAMETER;
39 }
40
41 if (pReq->size > cbReq)
42 {
43 dprintf(("VbglGRVerify: request size %d > buffer size %d\n", pReq->size, cbReq));
44 return VERR_INVALID_PARAMETER;
45 }
46
47 /* The request size must correspond to the request type. */
48 size_t cbReqExpected = vmmdevGetRequestSize(pReq->requestType);
49
50 if (cbReq < cbReqExpected)
51 {
52 dprintf(("VbglGRVerify: buffer size %d < expected size %d\n", cbReq, cbReqExpected));
53 return VERR_INVALID_PARAMETER;
54 }
55
56 if (cbReqExpected == cbReq)
57 {
58 /* This is most likely a fixed size request, and in this case the request size
59 * must be also equal to the expected size.
60 */
61 if (pReq->size != cbReqExpected)
62 {
63 dprintf(("VbglGRVerify: request size %d != expected size %d\n", pReq->size, cbReqExpected));
64 return VERR_INVALID_PARAMETER;
65 }
66
67 return VINF_SUCCESS;
68 }
69
70 /* This can be a variable size request. Check the request type and limit the size
71 * to VMMDEV_MAX_VMMDEVREQ_SIZE, which is max size supported by the host.
72 */
73 if ( pReq->requestType == VMMDevReq_LogString
74 || pReq->requestType == VMMDevReq_VideoSetVisibleRegion
75 || pReq->requestType == VMMDevReq_SetPointerShape
76#ifdef VBOX_WITH_64_BITS_GUESTS
77 || pReq->requestType == VMMDevReq_HGCMCall32
78 || pReq->requestType == VMMDevReq_HGCMCall64
79#else
80 || pReq->requestType == VMMDevReq_HGCMCall
81#endif /* VBOX_WITH_64_BITS_GUESTS */
82 || pReq->requestType == VMMDevReq_ChangeMemBalloon
83 || pReq->requestType == VMMDevReq_RegisterSharedModule)
84 {
85 if (cbReq > VMMDEV_MAX_VMMDEVREQ_SIZE)
86 {
87 dprintf(("VbglGRVerify: VMMDevReq_LogString: buffer size %d too big\n", cbReq));
88 return VERR_BUFFER_OVERFLOW; /* @todo is this error code ok? */
89 }
90 }
91 else
92 {
93 dprintf(("VbglGRVerify: request size %d > buffer size %d\n", pReq->size, cbReq));
94 return VERR_IO_BAD_LENGTH; /* @todo is this error code ok? */
95 }
96
97 return VINF_SUCCESS;
98}
99
100DECLVBGL(int) VbglGRAlloc (VMMDevRequestHeader **ppReq, uint32_t cbSize, VMMDevRequestType reqType)
101{
102 VMMDevRequestHeader *pReq;
103 int rc = vbglR0Enter ();
104
105 if (RT_FAILURE(rc))
106 return rc;
107
108 if (!ppReq || cbSize < sizeof (VMMDevRequestHeader))
109 {
110 dprintf(("VbglGRAlloc: Invalid parameter: ppReq = %p, cbSize = %d\n", ppReq, cbSize));
111 return VERR_INVALID_PARAMETER;
112 }
113
114 pReq = (VMMDevRequestHeader *)VbglPhysHeapAlloc (cbSize);
115 if (!pReq)
116 {
117 AssertMsgFailed(("VbglGRAlloc: no memory\n"));
118 rc = VERR_NO_MEMORY;
119 }
120 else
121 {
122 memset(pReq, 0xAA, cbSize);
123
124 pReq->size = cbSize;
125 pReq->version = VMMDEV_REQUEST_HEADER_VERSION;
126 pReq->requestType = reqType;
127 pReq->rc = VERR_GENERAL_FAILURE;
128 pReq->reserved1 = 0;
129 pReq->reserved2 = 0;
130
131 *ppReq = pReq;
132 }
133
134 return rc;
135}
136
137DECLVBGL(int) VbglGRPerform (VMMDevRequestHeader *pReq)
138{
139 RTCCPHYS physaddr;
140 int rc = vbglR0Enter ();
141
142 if (RT_FAILURE(rc))
143 return rc;
144
145 if (!pReq)
146 return VERR_INVALID_PARAMETER;
147
148 physaddr = VbglPhysHeapGetPhysAddr (pReq);
149 if ( !physaddr
150 || (physaddr >> 32) != 0) /* Port IO is 32 bit. */
151 {
152 rc = VERR_VBGL_INVALID_ADDR;
153 }
154 else
155 {
156 ASMOutU32(g_vbgldata.portVMMDev + VMMDEV_PORT_OFF_REQUEST, (uint32_t)physaddr);
157 /* Make the compiler aware that the host has changed memory. */
158 ASMCompilerBarrier();
159 rc = pReq->rc;
160 }
161 return rc;
162}
163
164DECLVBGL(void) VbglGRFree (VMMDevRequestHeader *pReq)
165{
166 int rc = vbglR0Enter ();
167
168 if (RT_FAILURE(rc))
169 return;
170
171 VbglPhysHeapFree (pReq);
172}
173
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