[USBSTOR] Register dumb IRP_MJ_SYSTEM_CONTROL handler.
[reactos.git] / drivers / usb / usbstor / usbstor.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: USB block storage device driver.
5 * COPYRIGHT: 2005-2006 James Tabor
6 * 2011-2012 Michael Martin (michael.martin@reactos.org)
7 * 2011-2013 Johannes Anderwald (johannes.anderwald@reactos.org)
8 */
9
10 #include "usbstor.h"
11
12 #define NDEBUG
13 #include <debug.h>
14
15
16 NTSTATUS
17 NTAPI
18 USBSTOR_AddDevice(
19 IN PDRIVER_OBJECT DriverObject,
20 IN PDEVICE_OBJECT PhysicalDeviceObject)
21 {
22 NTSTATUS Status;
23 PDEVICE_OBJECT DeviceObject;
24 PFDO_DEVICE_EXTENSION DeviceExtension;
25
26 Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), 0, FILE_DEVICE_BUS_EXTENDER, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject);
27 if (!NT_SUCCESS(Status))
28 {
29 DPRINT1("USBSTOR_AddDevice: Failed to create FDO Status %x\n", Status);
30 return Status;
31 }
32
33 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
34 ASSERT(DeviceExtension);
35 RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
36
37 // initialize device extension
38 DeviceExtension->Common.IsFDO = TRUE;
39 DeviceExtension->FunctionalDeviceObject = DeviceObject;
40 DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
41 DeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
42
43 KeInitializeSpinLock(&DeviceExtension->CommonLock);
44
45 IoInitializeTimer(DeviceObject, USBSTOR_TimerRoutine, (PVOID)DeviceExtension);
46
47 // did attaching fail
48 if (!DeviceExtension->LowerDeviceObject)
49 {
50 IoDeleteDevice(DeviceObject);
51
52 return STATUS_DEVICE_REMOVED;
53 }
54
55 DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
56
57 // device is initialized
58 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
59
60 return STATUS_SUCCESS;
61 }
62
63 VOID
64 NTAPI
65 USBSTOR_Unload(
66 PDRIVER_OBJECT DriverObject)
67 {
68 // no-op
69 }
70
71 NTSTATUS
72 NTAPI
73 USBSTOR_DispatchClose(
74 PDEVICE_OBJECT DeviceObject,
75 PIRP Irp)
76 {
77 // function always succeeds ;)
78 DPRINT("USBSTOR_DispatchClose\n");
79 Irp->IoStatus.Information = 0;
80 Irp->IoStatus.Status = STATUS_SUCCESS;
81 IoCompleteRequest(Irp, IO_NO_INCREMENT);
82 return STATUS_SUCCESS;
83 }
84
85 NTSTATUS
86 NTAPI
87 USBSTOR_DispatchDeviceControl(
88 PDEVICE_OBJECT DeviceObject,
89 PIRP Irp)
90 {
91 NTSTATUS Status;
92
93 Status = USBSTOR_HandleDeviceControl(DeviceObject, Irp);
94 Irp->IoStatus.Status = Status;
95 IoCompleteRequest(Irp, IO_NO_INCREMENT);
96 return Status;
97 }
98
99 NTSTATUS
100 NTAPI
101 USBSTOR_DispatchScsi(
102 PDEVICE_OBJECT DeviceObject,
103 PIRP Irp)
104 {
105 return USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
106 }
107
108 NTSTATUS
109 NTAPI
110 USBSTOR_DispatchReadWrite(
111 PDEVICE_OBJECT DeviceObject,
112 PIRP Irp)
113 {
114 // read write ioctl is not supported
115 Irp->IoStatus.Information = 0;
116 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
117 IoCompleteRequest(Irp, IO_NO_INCREMENT);
118 return STATUS_INVALID_PARAMETER;
119 }
120
121 NTSTATUS
122 NTAPI
123 USBSTOR_DispatchPnp(
124 PDEVICE_OBJECT DeviceObject,
125 PIRP Irp)
126 {
127 PUSBSTOR_COMMON_DEVICE_EXTENSION DeviceExtension;
128
129 DeviceExtension = (PUSBSTOR_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
130
131 if (DeviceExtension->IsFDO)
132 {
133 return USBSTOR_FdoHandlePnp(DeviceObject, Irp);
134 }
135 else
136 {
137 return USBSTOR_PdoHandlePnp(DeviceObject, Irp);
138 }
139 }
140
141 NTSTATUS
142 NTAPI
143 USBSTOR_DispatchSystemControl(
144 IN PDEVICE_OBJECT DeviceObject,
145 IN PIRP Irp)
146 {
147 PUSBSTOR_COMMON_DEVICE_EXTENSION DeviceExtension = (PUSBSTOR_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
148 IoSkipCurrentIrpStackLocation(Irp);
149
150 if (DeviceExtension->IsFDO)
151 {
152 return IoCallDriver(((PFDO_DEVICE_EXTENSION)DeviceExtension)->LowerDeviceObject, Irp);
153 }
154 else
155 {
156 return IoCallDriver(((PPDO_DEVICE_EXTENSION)DeviceExtension)->LowerDeviceObject, Irp);
157 }
158 }
159
160 NTSTATUS
161 NTAPI
162 USBSTOR_DispatchPower(
163 PDEVICE_OBJECT DeviceObject,
164 PIRP Irp)
165 {
166 PFDO_DEVICE_EXTENSION DeviceExtension;
167
168 // get common device extension
169 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
170
171 if (DeviceExtension->Common.IsFDO)
172 {
173 PoStartNextPowerIrp(Irp);
174 IoSkipCurrentIrpStackLocation(Irp);
175 return PoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
176 }
177 else
178 {
179 PoStartNextPowerIrp(Irp);
180 Irp->IoStatus.Status = STATUS_SUCCESS;
181 IoCompleteRequest(Irp, IO_NO_INCREMENT);
182 return STATUS_SUCCESS;
183 }
184 }
185
186 NTSTATUS
187 NTAPI
188 DriverEntry(
189 IN PDRIVER_OBJECT DriverObject,
190 IN PUNICODE_STRING RegPath)
191 {
192
193 DPRINT("********* USB Storage *********\n");
194
195 DriverObject->DriverUnload = USBSTOR_Unload;
196 DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice;
197 DriverObject->DriverStartIo = USBSTOR_StartIo;
198 DriverObject->MajorFunction[IRP_MJ_CREATE] = USBSTOR_DispatchClose;
199 DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBSTOR_DispatchClose;
200 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBSTOR_DispatchDeviceControl; // scsi pass through requests
201 DriverObject->MajorFunction[IRP_MJ_READ] = USBSTOR_DispatchReadWrite;
202 DriverObject->MajorFunction[IRP_MJ_WRITE] = USBSTOR_DispatchReadWrite;
203 DriverObject->MajorFunction[IRP_MJ_SCSI] = USBSTOR_DispatchScsi;
204 DriverObject->MajorFunction[IRP_MJ_PNP] = USBSTOR_DispatchPnp;
205 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = USBSTOR_DispatchSystemControl;
206 DriverObject->MajorFunction[IRP_MJ_POWER] = USBSTOR_DispatchPower;
207
208 return STATUS_SUCCESS;
209 }