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