VirtualBox

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

Last change on this file since 77923 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1/* $Id: VBoxMFDriver.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * VBox Mouse Filter Driver - Interface functions.
4 */
5
6/*
7 * Copyright (C) 2011-2019 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
18#include "VBoxMF.h"
19#include <VBox/VBoxGuestLib.h>
20#include <iprt/initterm.h>
21#include <iprt/assert.h>
22
23#ifdef ALLOC_PRAGMA
24# pragma alloc_text(INIT, DriverEntry)
25#endif
26
27/* Driver entry point */
28NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
29{
30 NOREF(RegistryPath);
31 PAGED_CODE();
32LOGREL(("DriverEntry:"));
33
34 int irc = RTR0Init(0);
35 if (RT_FAILURE(irc))
36 {
37 LOGREL(("failed to init IPRT (rc=%#x)", irc));
38 return STATUS_INTERNAL_ERROR;
39 }
40 LOGF_ENTER();
41
42 DriverObject->DriverUnload = VBoxDrvUnload;
43 DriverObject->DriverExtension->AddDevice = VBoxDrvAddDevice;
44
45 for (int i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
46 DriverObject->MajorFunction[i] = VBoxIrpPassthrough;
47 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = VBoxIrpInternalIOCTL;
48 DriverObject->MajorFunction[IRP_MJ_PNP] = VBoxIrpPnP;
49 DriverObject->MajorFunction[IRP_MJ_POWER] = VBoxIrpPower;
50
51 VBoxMouFltInitGlobals();
52 LOGF_LEAVE();
53 return STATUS_SUCCESS;
54}
55
56VOID VBoxDrvUnload(IN PDRIVER_OBJECT Driver)
57{
58 NOREF(Driver);
59 PAGED_CODE();
60 LOGF_ENTER();
61
62 VBoxMouFltDeleteGlobals();
63 RTR0Term();
64}
65
66#define VBOXUSB_RLTAG 'LRBV'
67
68NTSTATUS VBoxDrvAddDevice(IN PDRIVER_OBJECT Driver, IN PDEVICE_OBJECT PDO)
69{
70 NTSTATUS rc;
71 PDEVICE_OBJECT pDO, pDOParent;
72 PVBOXMOUSE_DEVEXT pDevExt;
73
74 PAGED_CODE();
75 LOGF_ENTER();
76
77 rc = IoCreateDevice(Driver, sizeof(VBOXMOUSE_DEVEXT), NULL, FILE_DEVICE_MOUSE, 0, FALSE, &pDO);
78 if (!NT_SUCCESS(rc))
79 {
80 WARN(("IoCreateDevice failed with %#x", rc));
81 return rc;
82 }
83
84 pDevExt = (PVBOXMOUSE_DEVEXT) pDO->DeviceExtension;
85 RtlZeroMemory(pDevExt, sizeof(VBOXMOUSE_DEVEXT));
86
87 IoInitializeRemoveLock(&pDevExt->RemoveLock, VBOXUSB_RLTAG, 1, 100);
88
89 rc = IoAcquireRemoveLock(&pDevExt->RemoveLock, pDevExt);
90 if (!NT_SUCCESS(rc))
91 {
92 WARN(("IoAcquireRemoveLock failed with %#x", rc));
93 IoDeleteDevice(pDO);
94 return rc;
95 }
96
97 pDOParent = IoAttachDeviceToDeviceStack(pDO, PDO);
98 if (!pDOParent)
99 {
100 IoReleaseRemoveLockAndWait(&pDevExt->RemoveLock, pDevExt);
101
102 WARN(("IoAttachDeviceToDeviceStack failed"));
103 IoDeleteDevice(pDO);
104 return STATUS_DEVICE_NOT_CONNECTED;
105 }
106
107 pDevExt->pdoMain = PDO;
108 pDevExt->pdoSelf = pDO;
109 pDevExt->pdoParent = pDOParent;
110
111 VBoxDeviceAdded(pDevExt);
112
113 pDO->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
114 pDO->Flags &= ~DO_DEVICE_INITIALIZING;
115
116 LOGF_LEAVE();
117 return rc;
118}
119
120NTSTATUS VBoxIrpPassthrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
121{
122 PVBOXMOUSE_DEVEXT pDevExt;
123 LOGF_ENTER();
124
125 pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;
126
127 IoSkipCurrentIrpStackLocation(Irp);
128
129 LOGF_LEAVE();
130 return IoCallDriver(pDevExt->pdoParent, Irp);
131}
132
133static void
134VBoxServiceCB(PDEVICE_OBJECT DeviceObject, PMOUSE_INPUT_DATA InputDataStart,
135 PMOUSE_INPUT_DATA InputDataEnd, PULONG InputDataConsumed)
136{
137 PVBOXMOUSE_DEVEXT pDevExt;
138 LOGF_ENTER();
139
140 pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;
141
142 VBoxDrvNotifyServiceCB(pDevExt, InputDataStart, InputDataEnd, InputDataConsumed);
143
144 LOGF_LEAVE();
145}
146
147NTSTATUS VBoxIrpInternalIOCTL(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
148{
149 PIO_STACK_LOCATION pStack;
150 PVBOXMOUSE_DEVEXT pDevExt;
151 LOGF_ENTER();
152
153 pStack = IoGetCurrentIrpStackLocation(Irp);
154 pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;
155
156 LOGF(("IOCTL %08X, fn = %#04X", pStack->Parameters.DeviceIoControl.IoControlCode,
157 (pStack->Parameters.DeviceIoControl.IoControlCode>>2)&0xFFF));
158
159 /* Hook into connection between mouse class device and port drivers */
160 if (pStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_MOUSE_CONNECT)
161 {
162 Irp->IoStatus.Information = 0;
163
164 if (pDevExt->OriginalConnectData.pfnServiceCB)
165 {
166 WARN(("STATUS_SHARING_VIOLATION"));
167 Irp->IoStatus.Status = STATUS_SHARING_VIOLATION;
168 IoCompleteRequest(Irp, IO_NO_INCREMENT);
169 return Irp->IoStatus.Status;
170 }
171
172 if (pStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(INTERNAL_MOUSE_CONNECT_DATA))
173 {
174 WARN(("STATUS_INVALID_PARAMETER"));
175 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
176 IoCompleteRequest(Irp, IO_NO_INCREMENT);
177 return Irp->IoStatus.Status;
178 }
179
180 PINTERNAL_MOUSE_CONNECT_DATA pData = (PINTERNAL_MOUSE_CONNECT_DATA) pStack->Parameters.DeviceIoControl.Type3InputBuffer;
181
182 pDevExt->OriginalConnectData = *pData;
183 pData->pDO = pDevExt->pdoSelf;
184 pData->pfnServiceCB = VBoxServiceCB;
185 }
186
187 VBoxInformHost(pDevExt);
188
189 LOGF_LEAVE();
190 return VBoxIrpPassthrough(DeviceObject, Irp);
191}
192
193NTSTATUS VBoxIrpPnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
194{
195 PIO_STACK_LOCATION pStack;
196 PVBOXMOUSE_DEVEXT pDevExt;
197 NTSTATUS rc;
198 LOGF_ENTER();
199
200 pStack = IoGetCurrentIrpStackLocation(Irp);
201 pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;
202
203 switch (pStack->MinorFunction)
204 {
205 case IRP_MN_REMOVE_DEVICE:
206 {
207 LOGF(("IRP_MN_REMOVE_DEVICE"));
208
209 IoReleaseRemoveLockAndWait(&pDevExt->RemoveLock, pDevExt);
210
211 VBoxDeviceRemoved(pDevExt);
212
213 Irp->IoStatus.Status = STATUS_SUCCESS;
214 rc = VBoxIrpPassthrough(DeviceObject, Irp);
215
216 IoDetachDevice(pDevExt->pdoParent);
217 IoDeleteDevice(DeviceObject);
218 break;
219 }
220 default:
221 {
222 rc = VBoxIrpPassthrough(DeviceObject, Irp);
223 break;
224 }
225 }
226
227 if (!NT_SUCCESS(rc) && rc != STATUS_NOT_SUPPORTED)
228 {
229 WARN(("rc=%#x", rc));
230 }
231
232 LOGF_LEAVE();
233 return rc;
234}
235
236NTSTATUS VBoxIrpPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
237{
238 PVBOXMOUSE_DEVEXT pDevExt;
239 PAGED_CODE();
240 LOGF_ENTER();
241 pDevExt = (PVBOXMOUSE_DEVEXT) DeviceObject->DeviceExtension;
242 PoStartNextPowerIrp(Irp);
243 IoSkipCurrentIrpStackLocation(Irp);
244 LOGF_LEAVE();
245 return PoCallDriver(pDevExt->pdoParent, Irp);
246}
247
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