VirtualBox

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

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

HostDrivers: Updated (C) year.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 KB
Line 
1/* $Id: VBoxUsbPnP.cpp 56293 2015-06-09 14:23:56Z vboxsync $ */
2/** @file
3 * USB PnP Handling
4 */
5/*
6 * Copyright (C) 2011-2015 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
73 IoCopyCurrentIrpStackLocationToNext(pIrp);
74 Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
75 if (NT_SUCCESS(Status) && enmState == ENMVBOXUSB_PNPSTATE_STOP_PENDING)
76 {
77 vboxUsbPnPStateRestore(pDevExt);
78 }
79
80 Status = STATUS_SUCCESS;
81 VBoxDrvToolIoComplete(pIrp, Status, 0);
82 vboxUsbDdiStateRelease(pDevExt);
83
84 return Status;
85}
86
87static NTSTATUS vboxUsbPnPMnQueryRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
88{
89 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_REMOVE_PENDING);
90
91 vboxUsbDdiStateReleaseAndWaitCompleted(pDevExt);
92
93 pIrp->IoStatus.Status = STATUS_SUCCESS;
94 pIrp->IoStatus.Information = 0;
95 IoSkipCurrentIrpStackLocation(pIrp);
96 return IoCallDriver(pDevExt->pLowerDO, pIrp);
97}
98
99static NTSTATUS vboxUsbPnPRmDev(PVBOXUSBDEV_EXT pDevExt)
100{
101 NTSTATUS Status = vboxUsbRtRm(pDevExt);
102 Assert(Status == STATUS_SUCCESS);
103
104 return Status;
105}
106
107static NTSTATUS vboxUsbPnPMnRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
108{
109 ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
110 NTSTATUS Status = STATUS_SUCCESS;
111 if (enmState != ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED)
112 {
113 Status = vboxUsbPnPRmDev(pDevExt);
114 Assert(Status == STATUS_SUCCESS);
115 }
116
117 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_REMOVED);
118
119 vboxUsbDdiStateRelease(pDevExt);
120
121 vboxUsbDdiStateReleaseAndWaitRemoved(pDevExt);
122
123 vboxUsbRtClear(pDevExt);
124
125 pIrp->IoStatus.Status = STATUS_SUCCESS;
126 pIrp->IoStatus.Information = 0;
127 IoSkipCurrentIrpStackLocation(pIrp);
128 Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
129
130 IoDetachDevice(pDevExt->pLowerDO);
131 IoDeleteDevice(pDevExt->pFDO);
132
133 return Status;
134}
135
136static NTSTATUS vboxUsbPnPMnCancelRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
137{
138 ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
139 NTSTATUS Status = STATUS_SUCCESS;
140 IoCopyCurrentIrpStackLocationToNext(pIrp);
141
142 Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
143
144 if (NT_SUCCESS(Status) &&
145 enmState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING)
146 {
147 vboxUsbPnPStateRestore(pDevExt);
148 }
149
150 Status = STATUS_SUCCESS;
151 VBoxDrvToolIoComplete(pIrp, Status, 0);
152 vboxUsbDdiStateRelease(pDevExt);
153
154 return Status;
155}
156
157static NTSTATUS vboxUsbPnPMnSurpriseRemoval(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
158{
159 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED);
160
161 NTSTATUS Status = vboxUsbPnPRmDev(pDevExt);
162 Assert(Status == STATUS_SUCCESS);
163
164 pIrp->IoStatus.Status = STATUS_SUCCESS;
165 pIrp->IoStatus.Information = 0;
166 IoSkipCurrentIrpStackLocation(pIrp);
167 Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
168
169 vboxUsbDdiStateRelease(pDevExt);
170
171 return Status;
172}
173
174static NTSTATUS vboxUsbPnPMnQueryCapabilities(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
175{
176 PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
177 PDEVICE_CAPABILITIES pDevCaps = pSl->Parameters.DeviceCapabilities.Capabilities;
178
179 if (pDevCaps->Version < 1 || pDevCaps->Size < sizeof (*pDevCaps))
180 {
181 Assert(0);
182 /* todo: return more appropriate status ?? */
183 return STATUS_UNSUCCESSFUL;
184 }
185
186 pDevCaps->SurpriseRemovalOK = TRUE;
187 pIrp->IoStatus.Status = STATUS_SUCCESS;
188
189 IoCopyCurrentIrpStackLocationToNext(pIrp);
190 NTSTATUS Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
191 Assert(NT_SUCCESS(Status));
192 if (NT_SUCCESS(Status))
193 {
194 pDevCaps->SurpriseRemovalOK = 1;
195 pDevExt->DdiState.DevCaps = *pDevCaps;
196 }
197
198 VBoxDrvToolIoComplete(pIrp, Status, 0);
199 vboxUsbDdiStateRelease(pDevExt);
200
201 return Status;
202}
203
204static NTSTATUS vboxUsbPnPMnDefault(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
205{
206 NTSTATUS Status;
207 IoSkipCurrentIrpStackLocation(pIrp);
208 Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
209 vboxUsbDdiStateRelease(pDevExt);
210 return Status;
211}
212
213DECLHIDDEN(NTSTATUS) vboxUsbDispatchPnP(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
214{
215 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
216 ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
217 if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt))
218 {
219 return VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0);
220 }
221
222 PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
223
224 switch (pSl->MinorFunction)
225 {
226 case IRP_MN_START_DEVICE:
227 {
228 return vboxUsbPnPMnStartDevice(pDevExt, pIrp);
229 }
230 case IRP_MN_QUERY_STOP_DEVICE:
231 {
232 return vboxUsbPnPMnQueryStopDevice(pDevExt, pIrp);
233 }
234 case IRP_MN_STOP_DEVICE:
235 {
236 return vboxUsbPnPMnStopDevice(pDevExt, pIrp);
237 }
238 case IRP_MN_CANCEL_STOP_DEVICE:
239 {
240 return vboxUsbPnPMnCancelStopDevice(pDevExt, pIrp);
241 }
242 case IRP_MN_QUERY_REMOVE_DEVICE:
243 {
244 return vboxUsbPnPMnQueryRemoveDevice(pDevExt, pIrp);
245 }
246 case IRP_MN_REMOVE_DEVICE:
247 {
248 return vboxUsbPnPMnRemoveDevice(pDevExt, pIrp);
249 }
250 case IRP_MN_CANCEL_REMOVE_DEVICE:
251 {
252 return vboxUsbPnPMnCancelRemoveDevice(pDevExt, pIrp);
253 }
254 case IRP_MN_SURPRISE_REMOVAL:
255 {
256 return vboxUsbPnPMnSurpriseRemoval(pDevExt, pIrp);
257 }
258 case IRP_MN_QUERY_CAPABILITIES:
259 {
260 return vboxUsbPnPMnQueryCapabilities(pDevExt, pIrp);
261 }
262 default:
263 {
264 return vboxUsbPnPMnDefault(pDevExt, pIrp);
265 }
266 }
267}
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