1 /* libusb-win32, Generic Windows USB Library
2 * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19
20 #include "libusb_driver.h"
21
dispatch(DEVICE_OBJECT * device_object,IRP * irp)22 NTSTATUS DDKAPI dispatch(DEVICE_OBJECT *device_object, IRP *irp)
23 {
24 libusb_device_t *dev = device_object->DeviceExtension;
25 IO_STACK_LOCATION *stack_location = IoGetCurrentIrpStackLocation(irp);
26
27 switch (stack_location->MajorFunction)
28 {
29 case IRP_MJ_PNP:
30 return dispatch_pnp(dev, irp);
31
32 case IRP_MJ_POWER:
33 // ID: 2960644 (farthen)
34 // You can't set the power state if the device is not handled at all
35 if(!dev->next_stack_device)
36 {
37 return complete_irp(irp, STATUS_INVALID_DEVICE_STATE, 0);
38 }
39 return dispatch_power(dev, irp);
40 }
41
42 /* since this driver may run as an upper filter we have to check whether */
43 /* the IRP is sent to this device object or to the lower one */
44 if (accept_irp(dev, irp))
45 {
46 switch (stack_location->MajorFunction)
47 {
48 case IRP_MJ_DEVICE_CONTROL:
49
50 if (dev->is_started)
51 {
52 return dispatch_ioctl(dev, irp);
53 }
54 else /* not started yet */
55 {
56 return complete_irp(irp, STATUS_INVALID_DEVICE_STATE, 0);
57 }
58
59 case IRP_MJ_CREATE:
60
61 if (dev->is_started)
62 {
63 // only one driver can act as power policy owner and
64 // power_set_device_state() can only be issued by the PPO.
65 // disallow_power_control is set to true for drivers which
66 // we know cause a BSOD on any attempt to request power irps.
67 if (dev->power_state.DeviceState != PowerDeviceD0 && !dev->disallow_power_control)
68 {
69 /* power up the device, block until the call */
70 /* completes */
71 power_set_device_state(dev, PowerDeviceD0, TRUE);
72 }
73 return complete_irp(irp, STATUS_SUCCESS, 0);
74 }
75 else /* not started yet */
76 {
77 return complete_irp(irp, STATUS_INVALID_DEVICE_STATE, 0);
78 }
79
80 case IRP_MJ_CLOSE:
81
82 /* release all interfaces bound to this file object */
83 release_all_interfaces(dev, stack_location->FileObject);
84 return complete_irp(irp, STATUS_SUCCESS, 0);
85
86 case IRP_MJ_CLEANUP:
87
88 return complete_irp(irp, STATUS_SUCCESS, 0);
89
90 default:
91 return complete_irp(irp, STATUS_NOT_SUPPORTED, 0);
92 }
93 }
94 else /* the IRP is for the lower device object */
95 {
96 return pass_irp_down(dev, irp, NULL, NULL);
97 }
98 }
99
100