VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFInternal.cpp@ 37163

Last change on this file since 37163 was 37163, checked in by vboxsync, 14 years ago

VBoxMouse: new mouse filter driver

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1/* $Id: VBoxMFInternal.cpp 37163 2011-05-20 11:46:18Z vboxsync $ */
2
3/** @file
4 * VBox Mouse filter internal functions
5 */
6
7/*
8 * Copyright (C) 2011 Oracle Corporation
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
19#include "VBoxMF.h"
20#include <VBox/VBoxGuestLib.h>
21
22typedef struct _VBoxGlobalContext
23{
24 volatile LONG cDevicesStarted;
25 volatile LONG fVBGLInited;
26 volatile LONG fVBGLInitFailed;
27 volatile LONG fHostInformed;
28 volatile LONG fHostMouseFound;
29} VBoxGlobalContext;
30
31static VBoxGlobalContext g_ctx = {0, FALSE, FALSE, FALSE, FALSE};
32
33static BOOLEAN vboxIsVBGLInited(void)
34{
35 return InterlockedCompareExchange(&g_ctx.fVBGLInited, TRUE, TRUE) == TRUE;
36}
37
38static BOOLEAN vboxIsVBGLInitFailed (void)
39{
40 return InterlockedCompareExchange(&g_ctx.fVBGLInitFailed, TRUE, TRUE) == TRUE;
41}
42
43static BOOLEAN vboxIsHostInformed(void)
44{
45 return InterlockedCompareExchange(&g_ctx.fHostInformed, TRUE, TRUE) == TRUE;
46}
47
48static BOOLEAN vboxIsHostMouseFound(void)
49{
50 return InterlockedCompareExchange(&g_ctx.fHostMouseFound, TRUE, TRUE) == TRUE;
51}
52
53VOID VBoxDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt)
54{
55 LOGF_ENTER();
56 LONG callCnt = InterlockedIncrement(&g_ctx.cDevicesStarted);
57
58 /* One time Vbgl initialization */
59 if (callCnt == 1)
60 {
61 if (!vboxIsVBGLInited() && !vboxIsVBGLInitFailed())
62 {
63 int rc = VbglInit();
64
65 if (RT_SUCCESS(rc))
66 {
67 InterlockedExchange(&g_ctx.fVBGLInited, TRUE);
68 LOG(("VBGL init OK"));
69 }
70 else
71 {
72 InterlockedExchange (&g_ctx.fVBGLInitFailed, TRUE);
73 WARN(("VBGL init failed with rc=%#x", rc));
74 }
75 }
76 }
77
78 if (!vboxIsHostMouseFound())
79 {
80 NTSTATUS rc;
81 UCHAR buffer[512];
82 CM_RESOURCE_LIST *pResourceList = (CM_RESOURCE_LIST *)&buffer[0];
83 ULONG cbWritten=0;
84 BOOLEAN bDetected = FALSE;
85
86 rc = IoGetDeviceProperty(pDevExt->pdoMain, DevicePropertyBootConfiguration,
87 sizeof(buffer), &buffer[0], &cbWritten);
88 if (!NT_SUCCESS(rc))
89 {
90 WARN(("IoGetDeviceProperty failed with rc=%#x", rc));
91 return;
92 }
93
94 LOG(("Number of descriptors: %d", pResourceList->Count));
95
96 /* Check if device claims IO port 0x60 or int12 */
97 for (ULONG i=0; i<pResourceList->Count; ++i)
98 {
99 CM_FULL_RESOURCE_DESCRIPTOR *pFullDescriptor = &pResourceList->List[i];
100
101 LOG(("FullDescriptor[%i]: IfType %d, Bus %d, Ver %d, Rev %d, Count %d",
102 i, pFullDescriptor->InterfaceType, pFullDescriptor->BusNumber,
103 pFullDescriptor->PartialResourceList.Version, pFullDescriptor->PartialResourceList.Revision,
104 pFullDescriptor->PartialResourceList.Count));
105
106 for (ULONG j=0; j<pFullDescriptor->PartialResourceList.Count; ++j)
107 {
108 CM_PARTIAL_RESOURCE_DESCRIPTOR *pPartialDescriptor = &pFullDescriptor->PartialResourceList.PartialDescriptors[j];
109 LOG(("PartialDescriptor[%d]: type %d, ShareDisposition %d, Flags 0x%04X, Start 0x%llx, length 0x%x",
110 j, pPartialDescriptor->Type, pPartialDescriptor->ShareDisposition, pPartialDescriptor->Flags,
111 pPartialDescriptor->u.Generic.Start.QuadPart, pPartialDescriptor->u.Generic.Length));
112
113 switch(pPartialDescriptor->Type)
114 {
115 case CmResourceTypePort:
116 {
117 LOG(("CmResourceTypePort %#x", pPartialDescriptor->u.Port.Start.QuadPart));
118 if (pPartialDescriptor->u.Port.Start.QuadPart == 0x60)
119 {
120 bDetected = TRUE;
121 }
122 break;
123 }
124 case CmResourceTypeInterrupt:
125 {
126 LOG(("CmResourceTypeInterrupt %ld", pPartialDescriptor->u.Interrupt.Vector));
127 if (pPartialDescriptor->u.Interrupt.Vector == 0xC)
128 {
129 bDetected = TRUE;
130 }
131 break;
132 }
133 default:
134 {
135 break;
136 }
137 }
138 }
139 }
140
141 if (bDetected)
142 {
143 /* It's the emulated 8042 PS/2 mouse/kbd device, so mark it as the Host one.
144 * For this device the filter will query absolute mouse coords from the host.
145 */
146 InterlockedExchange(&g_ctx.fHostMouseFound, TRUE);
147
148 pDevExt->bHostMouse = TRUE;
149 LOG(("Host mouse found"));
150 }
151 }
152 LOGF_LEAVE();
153}
154
155VOID VBoxInformHost(PVBOXMOUSE_DEVEXT pDevExt)
156{
157 LOGF_ENTER();
158
159 if (!vboxIsVBGLInited())
160 {
161 WARN(("!vboxIsVBGLInited"));
162 return;
163 }
164
165 /* Inform host we support absolute coordinates */
166 if (pDevExt->bHostMouse && !vboxIsHostInformed())
167 {
168 VMMDevReqMouseStatus *req = NULL;
169 int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
170
171 if (RT_SUCCESS(rc))
172 {
173 req->mouseFeatures = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE;
174 req->pointerXPos = 0;
175 req->pointerYPos = 0;
176
177 rc = VbglGRPerform(&req->header);
178
179 if (RT_SUCCESS(rc))
180 {
181 InterlockedExchange(&g_ctx.fHostInformed, TRUE);
182 }
183 else
184 {
185 WARN(("VbglGRPerform failed with rc=%#x", rc));
186 }
187
188 VbglGRFree(&req->header);
189 }
190 else
191 {
192 WARN(("VbglGRAlloc failed with rc=%#x", rc));
193 }
194 }
195
196 /* Preallocate request to be used in VBoxServiceCB*/
197 if (pDevExt->bHostMouse && !pDevExt->pSCReq)
198 {
199 VMMDevReqMouseStatus *req = NULL;
200
201 int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_GetMouseStatus);
202
203 if (RT_SUCCESS(rc))
204 {
205 InterlockedExchangePointer((PVOID volatile *)&pDevExt->pSCReq, req);
206 }
207 else
208 {
209 WARN(("VbglGRAlloc for service callback failed with rc=%#x", rc));
210 }
211 }
212
213 LOGF_LEAVE();
214}
215
216VOID VBoxDeviceRemoved(PVBOXMOUSE_DEVEXT pDevExt)
217{
218 LOGF_ENTER();
219
220 /* Save the allocated request pointer and clear the devExt. */
221 VMMDevReqMouseStatus *pSCReq = (VMMDevReqMouseStatus *) InterlockedExchangePointer((PVOID volatile *)&pDevExt->pSCReq, NULL);
222
223 if (pDevExt->bHostMouse && vboxIsHostInformed())
224 {
225 // tell the VMM that from now on we can't handle absolute coordinates anymore
226 VMMDevReqMouseStatus *req = NULL;
227
228 int rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
229
230 if (RT_SUCCESS(rc))
231 {
232 req->mouseFeatures = 0;
233 req->pointerXPos = 0;
234 req->pointerYPos = 0;
235
236 rc = VbglGRPerform(&req->header);
237
238 if (RT_FAILURE(rc))
239 {
240 WARN(("VbglGRPerform failed with rc=%#x", rc));
241 }
242
243 VbglGRFree(&req->header);
244 }
245 else
246 {
247 WARN(("VbglGRAlloc failed with rc=%#x", rc));
248 }
249
250 InterlockedExchange(&g_ctx.fHostInformed, FALSE);
251 }
252
253 if (pSCReq)
254 {
255 VbglGRFree(&pSCReq->header);
256 }
257
258 LONG callCnt = InterlockedDecrement(&g_ctx.cDevicesStarted);
259
260 if (callCnt == 0)
261 {
262 if (vboxIsVBGLInited())
263 {
264 /* Set the flag to prevent reinitializing of the VBGL. */
265 InterlockedExchange(&g_ctx.fVBGLInitFailed, TRUE);
266
267 VbglTerminate();
268
269 /* The VBGL is now in the not initialized state. */
270 InterlockedExchange(&g_ctx.fVBGLInited, FALSE);
271 InterlockedExchange(&g_ctx.fVBGLInitFailed, FALSE);
272 }
273 }
274
275 LOGF_LEAVE();
276}
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