VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Mouse/NT5/VBoxMFDriver.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.0 KB
Line 
1/* $Id: VBoxMFDriver.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBox Mouse Filter Driver - Interface functions.
4 */
5
6/*
7 * Copyright (C) 2011-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#include "VBoxMF.h"
29#include <VBox/VBoxGuestLib.h>
30#include <iprt/initterm.h>
31#include <iprt/assert.h>
32
33#ifdef ALLOC_PRAGMA
34# pragma alloc_text(INIT, DriverEntry)
35#endif
36
37/* Driver entry point */
38NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
39{
40 NOREF(RegistryPath);
41 PAGED_CODE();
42LOGREL(("DriverEntry:"));
43
44 int irc = RTR0Init(0);
45 if (RT_FAILURE(irc))
46 {
47 LOGREL(("failed to init IPRT (rc=%#x)", irc));
48 return STATUS_INTERNAL_ERROR;
49 }
50 LOGF_ENTER();
51
52 DriverObject->DriverUnload = VBoxDrvUnload;
53 DriverObject->DriverExtension->AddDevice = VBoxDrvAddDevice;
54
55 for (int i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
56 DriverObject->MajorFunction[i] = VBoxIrpPassthrough;
57 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = VBoxIrpInternalIOCTL;
58 DriverObject->MajorFunction[IRP_MJ_PNP] = VBoxIrpPnP;
59 DriverObject->MajorFunction[IRP_MJ_POWER] = VBoxIrpPower;
60
61 VBoxMouFltInitGlobals();
62 LOGF_LEAVE();
63 return STATUS_SUCCESS;
64}
65
66VOID VBoxDrvUnload(IN PDRIVER_OBJECT Driver)
67{
68 NOREF(Driver);
69 PAGED_CODE();
70 LOGF_ENTER();
71
72 VBoxMouFltDeleteGlobals();
73 RTR0Term();
74}
75
76#define VBOXUSB_RLTAG 'LRBV'
77
78NTSTATUS VBoxDrvAddDevice(IN PDRIVER_OBJECT Driver, IN PDEVICE_OBJECT PDO)
79{
80 NTSTATUS rc;
81 PDEVICE_OBJECT pDO, pDOParent;
82 PVBOXMOUSE_DEVEXT pDevExt;
83
84 PAGED_CODE();
85 LOGF_ENTER();
86
87 rc = IoCreateDevice(Driver, sizeof(VBOXMOUSE_DEVEXT), NULL, FILE_DEVICE_MOUSE, 0, FALSE, &pDO);
88 if (!NT_SUCCESS(rc))
89 {
90 WARN(("IoCreateDevice failed with %#x", rc));
91 return rc;
92 }
93
94 pDevExt = (PVBOXMOUSE_DEVEXT) pDO->DeviceExtension;
95 RtlZeroMemory(pDevExt, sizeof(VBOXMOUSE_DEVEXT));
96
97 IoInitializeRemoveLock(&pDevExt->RemoveLock, VBOXUSB_RLTAG, 1, 100);
98
99 rc = IoAcquireRemoveLock(&pDevExt->RemoveLock, pDevExt);
100 if (!NT_SUCCESS(rc))
101 {
102 WARN(("IoAcquireRemoveLock failed with %#x", rc));
103 IoDeleteDevice(pDO);
104 return rc;
105 }
106
107 pDOParent = IoAttachDeviceToDeviceStack(pDO, PDO);
108 if (!pDOParent)
109 {
110 IoReleaseRemoveLockAndWait(&pDevExt->RemoveLock, pDevExt);
111
112 WARN(("IoAttachDeviceToDeviceStack failed"));
113 IoDeleteDevice(pDO);
114 return STATUS_DEVICE_NOT_CONNECTED;
115 }
116
117 pDevExt->pdoMain = PDO;
118 pDevExt->pdoSelf = pDO;
119 pDevExt->pdoParent = pDOParent;
120
121 VBoxDeviceAdded(pDevExt);
122
123 pDO->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
124 pDO->Flags &= ~DO_DEVICE_INITIALIZING;
125
126 LOGF_LEAVE();
127 return rc;
128}
129
130NTSTATUS VBoxIrpPassthrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
131{
132 PVBOXMOUSE_DEVEXT pDevExt;
133 LOGF_ENTER();
134
135 pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;
136
137 IoSkipCurrentIrpStackLocation(Irp);
138
139 LOGF_LEAVE();
140 return IoCallDriver(pDevExt->pdoParent, Irp);
141}
142
143static void
144VBoxServiceCB(PDEVICE_OBJECT DeviceObject, PMOUSE_INPUT_DATA InputDataStart,
145 PMOUSE_INPUT_DATA InputDataEnd, PULONG InputDataConsumed)
146{
147 PVBOXMOUSE_DEVEXT pDevExt;
148 LOGF_ENTER();
149
150 pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;
151
152 VBoxDrvNotifyServiceCB(pDevExt, InputDataStart, InputDataEnd, InputDataConsumed);
153
154 LOGF_LEAVE();
155}
156
157NTSTATUS VBoxIrpInternalIOCTL(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
158{
159 PIO_STACK_LOCATION pStack;
160 PVBOXMOUSE_DEVEXT pDevExt;
161 LOGF_ENTER();
162
163 pStack = IoGetCurrentIrpStackLocation(Irp);
164 pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;
165
166 LOGF(("IOCTL %08X, fn = %#04X", pStack->Parameters.DeviceIoControl.IoControlCode,
167 (pStack->Parameters.DeviceIoControl.IoControlCode>>2)&0xFFF));
168
169 /* Hook into connection between mouse class device and port drivers */
170 if (pStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_MOUSE_CONNECT)
171 {
172 Irp->IoStatus.Information = 0;
173
174 if (pDevExt->OriginalConnectData.pfnServiceCB)
175 {
176 WARN(("STATUS_SHARING_VIOLATION"));
177 Irp->IoStatus.Status = STATUS_SHARING_VIOLATION;
178 IoCompleteRequest(Irp, IO_NO_INCREMENT);
179 return Irp->IoStatus.Status;
180 }
181
182 if (pStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(INTERNAL_MOUSE_CONNECT_DATA))
183 {
184 WARN(("STATUS_INVALID_PARAMETER"));
185 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
186 IoCompleteRequest(Irp, IO_NO_INCREMENT);
187 return Irp->IoStatus.Status;
188 }
189
190 PINTERNAL_MOUSE_CONNECT_DATA pData = (PINTERNAL_MOUSE_CONNECT_DATA) pStack->Parameters.DeviceIoControl.Type3InputBuffer;
191
192 pDevExt->OriginalConnectData = *pData;
193 pData->pDO = pDevExt->pdoSelf;
194 pData->pfnServiceCB = VBoxServiceCB;
195 }
196
197 VBoxInformHost(pDevExt);
198
199 LOGF_LEAVE();
200 return VBoxIrpPassthrough(DeviceObject, Irp);
201}
202
203NTSTATUS VBoxIrpPnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
204{
205 PIO_STACK_LOCATION pStack;
206 PVBOXMOUSE_DEVEXT pDevExt;
207 NTSTATUS rc;
208 LOGF_ENTER();
209
210 pStack = IoGetCurrentIrpStackLocation(Irp);
211 pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;
212
213 switch (pStack->MinorFunction)
214 {
215 case IRP_MN_REMOVE_DEVICE:
216 {
217 LOGF(("IRP_MN_REMOVE_DEVICE"));
218
219 IoReleaseRemoveLockAndWait(&pDevExt->RemoveLock, pDevExt);
220
221 VBoxDeviceRemoved(pDevExt);
222
223 Irp->IoStatus.Status = STATUS_SUCCESS;
224 rc = VBoxIrpPassthrough(DeviceObject, Irp);
225
226 IoDetachDevice(pDevExt->pdoParent);
227 IoDeleteDevice(DeviceObject);
228 break;
229 }
230 default:
231 {
232 rc = VBoxIrpPassthrough(DeviceObject, Irp);
233 break;
234 }
235 }
236
237 if (!NT_SUCCESS(rc) && rc != STATUS_NOT_SUPPORTED)
238 {
239 WARN(("rc=%#x", rc));
240 }
241
242 LOGF_LEAVE();
243 return rc;
244}
245
246NTSTATUS VBoxIrpPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
247{
248 PVBOXMOUSE_DEVEXT pDevExt;
249 PAGED_CODE();
250 LOGF_ENTER();
251 pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;
252 PoStartNextPowerIrp(Irp);
253 IoSkipCurrentIrpStackLocation(Irp);
254 LOGF_LEAVE();
255 return PoCallDriver(pDevExt->pdoParent, Irp);
256}
257
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use