VirtualBox

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

Last change on this file since 66295 was 62699, checked in by vboxsync, 9 years ago

vboxUsbPnPStateGbgChange: Corrected seemingly incorrect state assertion (was always true).

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