VirtualBox

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

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

HostDrivers: warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.4 KB
Line 
1/* $Id: VBoxUsbPnP.cpp 62714 2016-07-29 21:41:09Z vboxsync $ */
2/** @file
3 * USB PnP Handling
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#include "VBoxUsbCmn.h"
19
20static NTSTATUS vboxUsbPnPMnStartDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
21{
22 IoCopyCurrentIrpStackLocationToNext(pIrp);
23 NTSTATUS Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
24 Assert(NT_SUCCESS(Status) || Status == STATUS_NOT_SUPPORTED);
25 if (NT_SUCCESS(Status))
26 {
27 Status = vboxUsbRtStart(pDevExt);
28 Assert(Status == STATUS_SUCCESS);
29 if (NT_SUCCESS(Status))
30 {
31 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_STARTED);
32 }
33 }
34
35 VBoxDrvToolIoComplete(pIrp, Status, 0);
36 vboxUsbDdiStateRelease(pDevExt);
37 return Status;
38}
39
40static NTSTATUS vboxUsbPnPMnQueryStopDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
41{
42 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_STOP_PENDING);
43
44 vboxUsbDdiStateReleaseAndWaitCompleted(pDevExt);
45
46 pIrp->IoStatus.Status = STATUS_SUCCESS;
47 pIrp->IoStatus.Information = 0;
48 IoSkipCurrentIrpStackLocation(pIrp);
49 return IoCallDriver(pDevExt->pLowerDO, pIrp);
50}
51
52static NTSTATUS vboxUsbPnPMnStopDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
53{
54 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_STOPPED);
55
56 vboxUsbRtClear(pDevExt);
57
58 NTSTATUS Status = VBoxUsbToolDevUnconfigure(pDevExt->pLowerDO);
59 Assert(NT_SUCCESS(Status));
60
61 pIrp->IoStatus.Status = Status;
62 pIrp->IoStatus.Information = 0;
63 IoSkipCurrentIrpStackLocation(pIrp);
64 Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
65
66 vboxUsbDdiStateRelease(pDevExt);
67 return Status;
68}
69
70static NTSTATUS vboxUsbPnPMnCancelStopDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
71{
72 ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
73 NTSTATUS Status = STATUS_SUCCESS;
74
75 IoCopyCurrentIrpStackLocationToNext(pIrp);
76 Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
77 if (NT_SUCCESS(Status) && enmState == ENMVBOXUSB_PNPSTATE_STOP_PENDING)
78 {
79 vboxUsbPnPStateRestore(pDevExt);
80 }
81
82 Status = STATUS_SUCCESS;
83 VBoxDrvToolIoComplete(pIrp, Status, 0);
84 vboxUsbDdiStateRelease(pDevExt);
85
86 return Status;
87}
88
89static NTSTATUS vboxUsbPnPMnQueryRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
90{
91 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_REMOVE_PENDING);
92
93 vboxUsbDdiStateReleaseAndWaitCompleted(pDevExt);
94
95 pIrp->IoStatus.Status = STATUS_SUCCESS;
96 pIrp->IoStatus.Information = 0;
97 IoSkipCurrentIrpStackLocation(pIrp);
98 return IoCallDriver(pDevExt->pLowerDO, pIrp);
99}
100
101static NTSTATUS vboxUsbPnPRmDev(PVBOXUSBDEV_EXT pDevExt)
102{
103 NTSTATUS Status = vboxUsbRtRm(pDevExt);
104 Assert(Status == STATUS_SUCCESS);
105
106 return Status;
107}
108
109static NTSTATUS vboxUsbPnPMnRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
110{
111 ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
112 NTSTATUS Status = STATUS_SUCCESS;
113 if (enmState != ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED)
114 {
115 Status = vboxUsbPnPRmDev(pDevExt);
116 Assert(Status == STATUS_SUCCESS);
117 }
118
119 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_REMOVED);
120
121 vboxUsbDdiStateRelease(pDevExt);
122
123 vboxUsbDdiStateReleaseAndWaitRemoved(pDevExt);
124
125 vboxUsbRtClear(pDevExt);
126
127 pIrp->IoStatus.Status = STATUS_SUCCESS;
128 pIrp->IoStatus.Information = 0;
129 IoSkipCurrentIrpStackLocation(pIrp);
130 Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
131
132 IoDetachDevice(pDevExt->pLowerDO);
133 IoDeleteDevice(pDevExt->pFDO);
134
135 return Status;
136}
137
138static NTSTATUS vboxUsbPnPMnCancelRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
139{
140 ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt);
141 NTSTATUS Status = STATUS_SUCCESS;
142 IoCopyCurrentIrpStackLocationToNext(pIrp);
143
144 Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
145
146 if (NT_SUCCESS(Status) &&
147 enmState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING)
148 {
149 vboxUsbPnPStateRestore(pDevExt);
150 }
151
152 Status = STATUS_SUCCESS;
153 VBoxDrvToolIoComplete(pIrp, Status, 0);
154 vboxUsbDdiStateRelease(pDevExt);
155
156 return Status;
157}
158
159static NTSTATUS vboxUsbPnPMnSurpriseRemoval(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
160{
161 vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED);
162
163 NTSTATUS Status = vboxUsbPnPRmDev(pDevExt);
164 Assert(Status == STATUS_SUCCESS);
165
166 pIrp->IoStatus.Status = STATUS_SUCCESS;
167 pIrp->IoStatus.Information = 0;
168 IoSkipCurrentIrpStackLocation(pIrp);
169 Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
170
171 vboxUsbDdiStateRelease(pDevExt);
172
173 return Status;
174}
175
176static NTSTATUS vboxUsbPnPMnQueryCapabilities(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
177{
178 PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
179 PDEVICE_CAPABILITIES pDevCaps = pSl->Parameters.DeviceCapabilities.Capabilities;
180
181 if (pDevCaps->Version < 1 || pDevCaps->Size < sizeof (*pDevCaps))
182 {
183 AssertFailed();
184 /* todo: return more appropriate status ?? */
185 return STATUS_UNSUCCESSFUL;
186 }
187
188 pDevCaps->SurpriseRemovalOK = TRUE;
189 pIrp->IoStatus.Status = STATUS_SUCCESS;
190
191 IoCopyCurrentIrpStackLocationToNext(pIrp);
192 NTSTATUS Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp);
193 Assert(NT_SUCCESS(Status));
194 if (NT_SUCCESS(Status))
195 {
196 pDevCaps->SurpriseRemovalOK = 1;
197 pDevExt->DdiState.DevCaps = *pDevCaps;
198 }
199
200 VBoxDrvToolIoComplete(pIrp, Status, 0);
201 vboxUsbDdiStateRelease(pDevExt);
202
203 return Status;
204}
205
206static NTSTATUS vboxUsbPnPMnDefault(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
207{
208 NTSTATUS Status;
209 IoSkipCurrentIrpStackLocation(pIrp);
210 Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
211 vboxUsbDdiStateRelease(pDevExt);
212 return Status;
213}
214
215DECLHIDDEN(NTSTATUS) vboxUsbDispatchPnP(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
216{
217 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
218 if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt))
219 return VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0);
220
221 PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
222 switch (pSl->MinorFunction)
223 {
224 case IRP_MN_START_DEVICE:
225 return vboxUsbPnPMnStartDevice(pDevExt, pIrp);
226
227 case IRP_MN_QUERY_STOP_DEVICE:
228 return vboxUsbPnPMnQueryStopDevice(pDevExt, pIrp);
229
230 case IRP_MN_STOP_DEVICE:
231 return vboxUsbPnPMnStopDevice(pDevExt, pIrp);
232
233 case IRP_MN_CANCEL_STOP_DEVICE:
234 return vboxUsbPnPMnCancelStopDevice(pDevExt, pIrp);
235
236 case IRP_MN_QUERY_REMOVE_DEVICE:
237 return vboxUsbPnPMnQueryRemoveDevice(pDevExt, pIrp);
238
239 case IRP_MN_REMOVE_DEVICE:
240 return vboxUsbPnPMnRemoveDevice(pDevExt, pIrp);
241
242 case IRP_MN_CANCEL_REMOVE_DEVICE:
243 return vboxUsbPnPMnCancelRemoveDevice(pDevExt, pIrp);
244
245 case IRP_MN_SURPRISE_REMOVAL:
246 return vboxUsbPnPMnSurpriseRemoval(pDevExt, pIrp);
247
248 case IRP_MN_QUERY_CAPABILITIES:
249 return vboxUsbPnPMnQueryCapabilities(pDevExt, pIrp);
250
251 default:
252 return vboxUsbPnPMnDefault(pDevExt, pIrp);
253 }
254}
255
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