VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.cpp@ 93115

Last change on this file since 93115 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.0 KB
Line 
1/* $Id: VBoxUsbDev.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * VBoxUsbDev.cpp - USB device.
4 */
5
6/*
7 * Copyright (C) 2011-2022 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
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include "VBoxUsbCmn.h"
32#include <iprt/assert.h>
33#include <VBox/log.h>
34
35
36/*********************************************************************************************************************************
37* Defined Constants And Macros *
38*********************************************************************************************************************************/
39#define VBOXUSB_MEMTAG 'bUBV'
40
41
42
43DECLHIDDEN(PVOID) vboxUsbMemAlloc(SIZE_T cbBytes)
44{
45 PVOID pvMem = ExAllocatePoolWithTag(NonPagedPool, cbBytes, VBOXUSB_MEMTAG);
46 Assert(pvMem);
47 return pvMem;
48}
49
50DECLHIDDEN(PVOID) vboxUsbMemAllocZ(SIZE_T cbBytes)
51{
52 PVOID pvMem = vboxUsbMemAlloc(cbBytes);
53 if (pvMem)
54 {
55 RtlZeroMemory(pvMem, cbBytes);
56 }
57 return pvMem;
58}
59
60DECLHIDDEN(VOID) vboxUsbMemFree(PVOID pvMem)
61{
62 ExFreePoolWithTag(pvMem, VBOXUSB_MEMTAG);
63}
64
65VBOXUSB_GLOBALS g_VBoxUsbGlobals = {0};
66
67static NTSTATUS vboxUsbDdiAddDevice(PDRIVER_OBJECT pDriverObject,
68 PDEVICE_OBJECT pPDO)
69{
70 PDEVICE_OBJECT pFDO = NULL;
71 NTSTATUS Status = IoCreateDevice(pDriverObject,
72 sizeof (VBOXUSBDEV_EXT),
73 NULL, /* IN PUNICODE_STRING pDeviceName OPTIONAL */
74 FILE_DEVICE_UNKNOWN, /* IN DEVICE_TYPE DeviceType */
75 FILE_AUTOGENERATED_DEVICE_NAME, /* IN ULONG DeviceCharacteristics */
76 FALSE, /* IN BOOLEAN fExclusive */
77 &pFDO);
78 Assert(Status == STATUS_SUCCESS);
79 if (Status == STATUS_SUCCESS)
80 {
81 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pFDO->DeviceExtension;
82 /* init Device Object bits */
83 pFDO->Flags |= DO_DIRECT_IO;
84 if (pPDO->Flags & DO_POWER_PAGABLE)
85 pFDO->Flags |= DO_POWER_PAGABLE;
86
87
88 /* now init our state bits */
89
90 pDevExt->cHandles = 0;
91
92 pDevExt->pFDO = pFDO;
93 pDevExt->pPDO = pPDO;
94 pDevExt->pLowerDO = IoAttachDeviceToDeviceStack(pFDO, pPDO);
95 Assert(pDevExt->pLowerDO);
96 if (pDevExt->pLowerDO)
97 {
98 vboxUsbDdiStateInit(pDevExt);
99 Status = vboxUsbRtInit(pDevExt);
100 if (Status == STATUS_SUCCESS)
101 {
102 /* we're done! */
103 pFDO->Flags &= ~DO_DEVICE_INITIALIZING;
104 return STATUS_SUCCESS;
105 }
106
107 IoDetachDevice(pDevExt->pLowerDO);
108 }
109 else
110 Status = STATUS_NO_SUCH_DEVICE;
111
112 IoDeleteDevice(pFDO);
113 }
114
115 return Status;
116}
117
118static VOID vboxUsbDdiUnload(PDRIVER_OBJECT pDriverObject)
119{
120 RT_NOREF1(pDriverObject);
121 LogRel(("VBoxUsb::DriverUnload. Built Date (%s) Time (%s)\n", __DATE__, __TIME__));
122 VBoxDrvToolStrFree(&g_VBoxUsbGlobals.RegPath);
123
124 vboxUsbRtGlobalsTerm();
125
126 PRTLOGGER pLogger = RTLogRelSetDefaultInstance(NULL);
127 if (pLogger)
128 {
129 RTLogDestroy(pLogger);
130 }
131 pLogger = RTLogSetDefaultInstance(NULL);
132 if (pLogger)
133 {
134 RTLogDestroy(pLogger);
135 }
136}
137
138static NTSTATUS vboxUsbDispatchCreate(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
139{
140 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
141 NTSTATUS Status = STATUS_INVALID_HANDLE;
142 do
143 {
144 if (vboxUsbPnPStateGet(pDevExt) != ENMVBOXUSB_PNPSTATE_STARTED)
145 {
146 Status = STATUS_INVALID_DEVICE_STATE;
147 break;
148 }
149
150 PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
151 PFILE_OBJECT pFObj = pSl->FileObject;
152 if (!pFObj)
153 {
154 Status = STATUS_INVALID_PARAMETER;
155 break;
156 }
157
158 pFObj->FsContext = NULL;
159
160 if (pFObj->FileName.Length)
161 {
162 Status = STATUS_INVALID_PARAMETER;
163 break;
164 }
165
166 Status = vboxUsbRtCreate(pDevExt, pIrp);
167 if (!NT_SUCCESS(Status))
168 {
169 AssertFailed();
170 break;
171 }
172
173 ASMAtomicIncU32(&pDevExt->cHandles);
174 Status = STATUS_SUCCESS;
175 break;
176 } while (0);
177
178 Status = VBoxDrvToolIoComplete(pIrp, Status, 0);
179 return Status;
180}
181
182static NTSTATUS vboxUsbDispatchClose(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
183{
184 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
185 NTSTATUS Status = STATUS_SUCCESS;
186#ifdef VBOX_STRICT
187 PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
188 PFILE_OBJECT pFObj = pSl->FileObject;
189 Assert(pFObj);
190 Assert(!pFObj->FileName.Length);
191#endif
192 Status = vboxUsbRtClose(pDevExt, pIrp);
193 if (NT_SUCCESS(Status))
194 {
195 ASMAtomicDecU32(&pDevExt->cHandles);
196 }
197 else
198 {
199 AssertFailed();
200 }
201 Status = VBoxDrvToolIoComplete(pIrp, Status, 0);
202 return Status;
203}
204
205static NTSTATUS vboxUsbDispatchDeviceControl(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
206{
207 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
208 if (vboxUsbDdiStateRetainIfStarted(pDevExt))
209 return vboxUsbRtDispatch(pDevExt, pIrp);
210 return VBoxDrvToolIoComplete(pIrp, STATUS_INVALID_DEVICE_STATE, 0);
211}
212
213static NTSTATUS vboxUsbDispatchCleanup(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
214{
215 RT_NOREF1(pDeviceObject);
216 return VBoxDrvToolIoComplete(pIrp, STATUS_SUCCESS, 0);
217}
218
219static NTSTATUS vboxUsbDevAccessDeviedDispatchStub(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
220{
221 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
222 if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt))
223 {
224 VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0);
225 return STATUS_DELETE_PENDING;
226 }
227
228 NTSTATUS Status = VBoxDrvToolIoComplete(pIrp, STATUS_ACCESS_DENIED, 0);
229
230 vboxUsbDdiStateRelease(pDevExt);
231
232 return Status;
233}
234
235static NTSTATUS vboxUsbDispatchSystemControl(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
236{
237 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
238 if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt))
239 {
240 VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0);
241 return STATUS_DELETE_PENDING;
242 }
243
244 IoSkipCurrentIrpStackLocation(pIrp);
245
246 NTSTATUS Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
247
248 vboxUsbDdiStateRelease(pDevExt);
249
250 return Status;
251}
252
253static NTSTATUS vboxUsbDispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
254{
255#ifdef DEBUG_misha
256 AssertFailed();
257#endif
258 return vboxUsbDevAccessDeviedDispatchStub(pDeviceObject, pIrp);
259}
260
261static NTSTATUS vboxUsbDispatchWrite(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
262{
263#ifdef DEBUG_misha
264 AssertFailed();
265#endif
266 return vboxUsbDevAccessDeviedDispatchStub(pDeviceObject, pIrp);
267}
268
269RT_C_DECLS_BEGIN
270
271NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath);
272
273RT_C_DECLS_END
274
275NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
276{
277 LogRel(("VBoxUsb::DriverEntry. Built Date (%s) Time (%s)\n", __DATE__, __TIME__));
278
279 NTSTATUS Status = vboxUsbRtGlobalsInit();
280 Assert(Status == STATUS_SUCCESS);
281 if (Status == STATUS_SUCCESS)
282 {
283 Status = VBoxDrvToolStrCopy(&g_VBoxUsbGlobals.RegPath, pRegistryPath);
284 Assert(Status == STATUS_SUCCESS);
285 if (Status == STATUS_SUCCESS)
286 {
287 g_VBoxUsbGlobals.pDrvObj = pDriverObject;
288
289 pDriverObject->DriverExtension->AddDevice = vboxUsbDdiAddDevice;
290
291 pDriverObject->DriverUnload = vboxUsbDdiUnload;
292
293 pDriverObject->MajorFunction[IRP_MJ_CREATE] = vboxUsbDispatchCreate;
294 pDriverObject->MajorFunction[IRP_MJ_CLOSE] = vboxUsbDispatchClose;
295 pDriverObject->MajorFunction[IRP_MJ_READ] = vboxUsbDispatchRead;
296 pDriverObject->MajorFunction[IRP_MJ_WRITE] = vboxUsbDispatchWrite;
297 pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = vboxUsbDispatchDeviceControl;
298 pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = vboxUsbDispatchCleanup;
299 pDriverObject->MajorFunction[IRP_MJ_POWER] = vboxUsbDispatchPower;
300 pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = vboxUsbDispatchSystemControl;
301 pDriverObject->MajorFunction[IRP_MJ_PNP] = vboxUsbDispatchPnP;
302
303 return STATUS_SUCCESS;
304 }
305 vboxUsbRtGlobalsTerm();
306 }
307
308 LogRel(("VBoxUsb::DriverEntry. failed with Status (0x%x)\n", Status));
309
310 return Status;
311}
312
313#ifdef VBOX_STRICT
314DECLHIDDEN(VOID) vboxUsbPnPStateGbgChange(ENMVBOXUSB_PNPSTATE enmOldState, ENMVBOXUSB_PNPSTATE enmNewState)
315{
316 /* *ensure the state change is valid */
317 switch (enmNewState)
318 {
319 case ENMVBOXUSB_PNPSTATE_STARTED:
320 Assert( enmOldState == ENMVBOXUSB_PNPSTATE_START_PENDING
321 || enmOldState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING
322 || enmOldState == ENMVBOXUSB_PNPSTATE_STOPPED
323 || enmOldState == ENMVBOXUSB_PNPSTATE_STOP_PENDING);
324 break;
325 case ENMVBOXUSB_PNPSTATE_STOP_PENDING:
326 Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STARTED);
327 break;
328 case ENMVBOXUSB_PNPSTATE_STOPPED:
329 Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STOP_PENDING);
330 break;
331 case ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED:
332 Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STARTED);
333 break;
334 case ENMVBOXUSB_PNPSTATE_REMOVE_PENDING:
335 Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STARTED);
336 break;
337 case ENMVBOXUSB_PNPSTATE_REMOVED:
338 Assert( enmOldState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING
339 || enmOldState == ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED);
340 break;
341 default:
342 AssertFailed();
343 break;
344 }
345
346}
347#endif
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