VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbPnP.cpp@ 55078

Last change on this file since 55078 was 55078, checked in by vboxsync, 10 years ago

5.0.0 Beta 1 (and backed out r99347 as it might have caused a regression)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.8 KB
Line 
1/* $Id: VBoxUsbPnP.cpp 55078 2015-04-01 14:50:42Z vboxsync $ */
2/** @file
3 * USB PnP Handling
4 */
5/*
6 * Copyright (C) 2011 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16#include "VBoxUsbCmn.h"
17
18static NTSTATUS vboxUsbPnPMnStartDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
19{
20 IoCopyCurrentIrpStackLocationToNext(pIrp);
21 NTSTATUS Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
22 Assert(NT_SUCCESS(Status) || Status == STATUS_NOT_SUPPORTED);
23 if (NT_SUCCESS(Status))
24 {
25 Status = vboxUsbRtStart(pDevExt);
26 Assert(Status == STATUS_SUCCESS);
27 if (NT_SUCCESS(Status))
28 {
29 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_STARTED);
30 }
31 }
32
33 VBoxDrvToolIoComplete(pIrp, Status, 0);
34 vboxUsbDdiStateRelease(pDevExt);
35 return Status;
36}
37
38static NTSTATUS vboxUsbPnPMnQueryStopDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
39{
40 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_STOP_PENDING);
41
42 vboxUsbDdiStateReleaseAndWaitCompleted(pDevExt);
43
44 pIrp->IoStatus.Status = STATUS_SUCCESS;
45 pIrp->IoStatus.Information = 0;
46 IoSkipCurrentIrpStackLocation(pIrp);
47 return IoCallDriver(pDevExt->pLowerDO, pIrp);
48}
49
50static NTSTATUS vboxUsbPnPMnStopDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
51{
52 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_STOPPED);
53
54 vboxUsbRtClear(pDevExt);
55
56 NTSTATUS Status = VBoxUsbToolDevUnconfigure(pDevExt->pLowerDO);
57 Assert(NT_SUCCESS(Status));
58
59 pIrp->IoStatus.Status = Status;
60 pIrp->IoStatus.Information = 0;
61 IoSkipCurrentIrpStackLocation(pIrp);
62 Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
63
64 vboxUsbDdiStateRelease(pDevExt);
65 return Status;
66}
67
68static NTSTATUS vboxUsbPnPMnCancelStopDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
69{
70 ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
71 NTSTATUS Status = STATUS_SUCCESS;
72 if (enmState == ENMVBOXUSB_PNPSTATE_STOP_PENDING)
73 {
74 IoCopyCurrentIrpStackLocationToNext(pIrp);
75 Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
76 if (NT_SUCCESS(Status))
77 {
78 vboxUsbPnPStateRestore(pDevExt);
79 }
80 }
81 else
82 {
83 Assert(0);
84 Assert(enmState == ENMVBOXUSB_PNPSTATE_STARTED);
85 }
86
87 VBoxDrvToolIoComplete(pIrp, Status, 0);
88 vboxUsbDdiStateRelease(pDevExt);
89
90 return Status;
91}
92
93static NTSTATUS vboxUsbPnPMnQueryRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
94{
95 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_REMOVE_PENDING);
96
97 vboxUsbDdiStateReleaseAndWaitCompleted(pDevExt);
98
99 pIrp->IoStatus.Status = STATUS_SUCCESS;
100 pIrp->IoStatus.Information = 0;
101 IoSkipCurrentIrpStackLocation(pIrp);
102 return IoCallDriver(pDevExt->pLowerDO, pIrp);
103}
104
105static NTSTATUS vboxUsbPnPRmDev(PVBOXUSBDEV_EXT pDevExt)
106{
107 NTSTATUS Status = vboxUsbRtRm(pDevExt);
108 Assert(Status == STATUS_SUCCESS);
109
110 return Status;
111}
112
113static NTSTATUS vboxUsbPnPMnRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
114{
115 ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
116 NTSTATUS Status = STATUS_SUCCESS;
117 if (enmState != ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED)
118 {
119 Status = vboxUsbPnPRmDev(pDevExt);
120 Assert(Status == STATUS_SUCCESS);
121 }
122
123 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_REMOVED);
124
125 vboxUsbDdiStateRelease(pDevExt);
126
127 vboxUsbDdiStateReleaseAndWaitRemoved(pDevExt);
128
129 vboxUsbRtClear(pDevExt);
130
131 pIrp->IoStatus.Status = STATUS_SUCCESS;
132 pIrp->IoStatus.Information = 0;
133 IoSkipCurrentIrpStackLocation(pIrp);
134 Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
135
136 IoDetachDevice(pDevExt->pLowerDO);
137 IoDeleteDevice(pDevExt->pFDO);
138
139 return Status;
140}
141
142static NTSTATUS vboxUsbPnPMnCancelRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
143{
144 ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
145 NTSTATUS Status = STATUS_SUCCESS;
146 if (enmState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING)
147 {
148 IoCopyCurrentIrpStackLocationToNext(pIrp);
149 Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
150 if (NT_SUCCESS(Status))
151 {
152 vboxUsbPnPStateRestore(pDevExt);
153 }
154 }
155 else
156 {
157 Assert(0);
158 Assert(enmState == ENMVBOXUSB_PNPSTATE_STARTED);
159 }
160
161 VBoxDrvToolIoComplete(pIrp, Status, 0);
162 vboxUsbDdiStateRelease(pDevExt);
163
164 return Status;
165}
166
167static NTSTATUS vboxUsbPnPMnSurpriseRemoval(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
168{
169 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED);
170
171 NTSTATUS Status = vboxUsbPnPRmDev(pDevExt);
172 Assert(Status == STATUS_SUCCESS);
173
174 pIrp->IoStatus.Status = STATUS_SUCCESS;
175 pIrp->IoStatus.Information = 0;
176 IoSkipCurrentIrpStackLocation(pIrp);
177 Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
178
179 vboxUsbDdiStateRelease(pDevExt);
180
181 return Status;
182}
183
184static NTSTATUS vboxUsbPnPMnQueryCapabilities(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
185{
186 PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
187 PDEVICE_CAPABILITIES pDevCaps = pSl->Parameters.DeviceCapabilities.Capabilities;
188
189 if (pDevCaps->Version < 1 || pDevCaps->Size < sizeof (*pDevCaps))
190 {
191 Assert(0);
192 /* todo: return more appropriate status ?? */
193 return STATUS_UNSUCCESSFUL;
194 }
195
196 pDevCaps->SurpriseRemovalOK = TRUE;
197 pIrp->IoStatus.Status = STATUS_SUCCESS;
198
199 IoCopyCurrentIrpStackLocationToNext(pIrp);
200 NTSTATUS Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
201 Assert(NT_SUCCESS(Status));
202 if (NT_SUCCESS(Status))
203 {
204 pDevCaps->SurpriseRemovalOK = 1;
205 pDevExt->DdiState.DevCaps = *pDevCaps;
206 }
207
208 VBoxDrvToolIoComplete(pIrp, Status, 0);
209 vboxUsbDdiStateRelease(pDevExt);
210
211 return Status;
212}
213
214static NTSTATUS vboxUsbPnPMnDefault(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
215{
216 NTSTATUS Status;
217 IoSkipCurrentIrpStackLocation(pIrp);
218 Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
219 vboxUsbDdiStateRelease(pDevExt);
220 return Status;
221}
222
223DECLHIDDEN(NTSTATUS) vboxUsbDispatchPnP(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
224{
225 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
226 ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
227 if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt))
228 {
229 return VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0);
230 }
231
232 PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
233
234 switch (pSl->MinorFunction)
235 {
236 case IRP_MN_START_DEVICE:
237 {
238 return vboxUsbPnPMnStartDevice(pDevExt, pIrp);
239 }
240 case IRP_MN_QUERY_STOP_DEVICE:
241 {
242 return vboxUsbPnPMnQueryStopDevice(pDevExt, pIrp);
243 }
244 case IRP_MN_STOP_DEVICE:
245 {
246 return vboxUsbPnPMnStopDevice(pDevExt, pIrp);
247 }
248 case IRP_MN_CANCEL_STOP_DEVICE:
249 {
250 return vboxUsbPnPMnCancelStopDevice(pDevExt, pIrp);
251 }
252 case IRP_MN_QUERY_REMOVE_DEVICE:
253 {
254 return vboxUsbPnPMnQueryRemoveDevice(pDevExt, pIrp);
255 }
256 case IRP_MN_REMOVE_DEVICE:
257 {
258 return vboxUsbPnPMnRemoveDevice(pDevExt, pIrp);
259 }
260 case IRP_MN_CANCEL_REMOVE_DEVICE:
261 {
262 return vboxUsbPnPMnCancelRemoveDevice(pDevExt, pIrp);
263 }
264 case IRP_MN_SURPRISE_REMOVAL:
265 {
266 return vboxUsbPnPMnSurpriseRemoval(pDevExt, pIrp);
267 }
268 case IRP_MN_QUERY_CAPABILITIES:
269 {
270 return vboxUsbPnPMnQueryCapabilities(pDevExt, pIrp);
271 }
272 default:
273 {
274 return vboxUsbPnPMnDefault(pDevExt, pIrp);
275 }
276 }
277}
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