1 /*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbstor/usbstor.c
5 * PURPOSE: USB block storage device driver.
6 * PROGRAMMERS:
7 * James Tabor
8 Johannes Anderwald
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include "usbstor.h"
14
15 #define NDEBUG
16 #include <debug.h>
17
18 /* PUBLIC AND PRIVATE FUNCTIONS **********************************************/
19
20 NTSTATUS
21 NTAPI
USBSTOR_AddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject)22 USBSTOR_AddDevice(
23 IN PDRIVER_OBJECT DriverObject,
24 IN PDEVICE_OBJECT PhysicalDeviceObject)
25 {
26 NTSTATUS Status;
27 PDEVICE_OBJECT DeviceObject;
28 PFDO_DEVICE_EXTENSION DeviceExtension;
29
30 //
31 // lets create the device
32 //
33 Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), 0, FILE_DEVICE_BUS_EXTENDER, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject);
34
35 //
36 // check for success
37 //
38 if (!NT_SUCCESS(Status))
39 {
40 DPRINT1("USBSTOR_AddDevice: Failed to create FDO Status %x\n", Status);
41 return Status;
42 }
43
44 //
45 // get device extension
46 //
47 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
48 ASSERT(DeviceExtension);
49
50 //
51 // zero device extension
52 //
53 RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
54
55 //
56 // initialize device extension
57 //
58 DeviceExtension->Common.IsFDO = TRUE;
59 DeviceExtension->FunctionalDeviceObject = DeviceObject;
60 DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
61 DeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
62
63 //
64 // init timer
65 //
66 IoInitializeTimer(DeviceObject, USBSTOR_TimerRoutine, (PVOID)DeviceExtension);
67
68 //
69 // did attaching fail
70 //
71 if (!DeviceExtension->LowerDeviceObject)
72 {
73 //
74 // device removed
75 //
76 IoDeleteDevice(DeviceObject);
77
78 return STATUS_DEVICE_REMOVED;
79 }
80
81 //
82 // set device flags
83 //
84 DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
85
86 //
87 // device is initialized
88 //
89 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
90
91
92 //
93 // done
94 //
95 return STATUS_SUCCESS;
96 }
97
98 VOID
99 NTAPI
USBSTOR_Unload(PDRIVER_OBJECT DriverObject)100 USBSTOR_Unload(
101 PDRIVER_OBJECT DriverObject)
102 {
103 //
104 // no-op
105 //
106 }
107
108 NTSTATUS
109 NTAPI
USBSTOR_DispatchClose(PDEVICE_OBJECT DeviceObject,PIRP Irp)110 USBSTOR_DispatchClose(
111 PDEVICE_OBJECT DeviceObject,
112 PIRP Irp)
113 {
114 //
115 // function always succeeds ;)
116 //
117 DPRINT("USBSTOR_DispatchClose\n");
118 Irp->IoStatus.Information = 0;
119 Irp->IoStatus.Status = STATUS_SUCCESS;
120 IoCompleteRequest(Irp, IO_NO_INCREMENT);
121 return STATUS_SUCCESS;
122 }
123
124
125 NTSTATUS
126 NTAPI
USBSTOR_DispatchDeviceControl(PDEVICE_OBJECT DeviceObject,PIRP Irp)127 USBSTOR_DispatchDeviceControl(
128 PDEVICE_OBJECT DeviceObject,
129 PIRP Irp)
130 {
131 NTSTATUS Status;
132
133 //
134 // handle requests
135 //
136 Status = USBSTOR_HandleDeviceControl(DeviceObject, Irp);
137
138 //
139 // complete request
140 //
141 Irp->IoStatus.Status = Status;
142 IoCompleteRequest(Irp, IO_NO_INCREMENT);
143
144 //
145 // done
146 //
147 return Status;
148 }
149
150
151 NTSTATUS
152 NTAPI
USBSTOR_DispatchScsi(PDEVICE_OBJECT DeviceObject,PIRP Irp)153 USBSTOR_DispatchScsi(
154 PDEVICE_OBJECT DeviceObject,
155 PIRP Irp)
156 {
157 //
158 // handle requests
159 //
160 return USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
161 }
162
163 NTSTATUS
164 NTAPI
USBSTOR_DispatchReadWrite(PDEVICE_OBJECT DeviceObject,PIRP Irp)165 USBSTOR_DispatchReadWrite(
166 PDEVICE_OBJECT DeviceObject,
167 PIRP Irp)
168 {
169 //
170 // read write ioctl is not supported
171 //
172 Irp->IoStatus.Information = 0;
173 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
174 IoCompleteRequest(Irp, IO_NO_INCREMENT);
175 return STATUS_INVALID_PARAMETER;
176 }
177
178 NTSTATUS
179 NTAPI
USBSTOR_DispatchPnp(PDEVICE_OBJECT DeviceObject,PIRP Irp)180 USBSTOR_DispatchPnp(
181 PDEVICE_OBJECT DeviceObject,
182 PIRP Irp)
183 {
184 PUSBSTOR_COMMON_DEVICE_EXTENSION DeviceExtension;
185
186 //
187 // get common device extension
188 //
189 DeviceExtension = (PUSBSTOR_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
190
191 //
192 // is it for the FDO
193 //
194 if (DeviceExtension->IsFDO)
195 {
196 //
197 // dispatch pnp request to fdo pnp handler
198 //
199 return USBSTOR_FdoHandlePnp(DeviceObject, Irp);
200 }
201 else
202 {
203 //
204 // dispatch request to pdo pnp handler
205 //
206 return USBSTOR_PdoHandlePnp(DeviceObject, Irp);
207 }
208 }
209
210 NTSTATUS
211 NTAPI
USBSTOR_DispatchPower(PDEVICE_OBJECT DeviceObject,PIRP Irp)212 USBSTOR_DispatchPower(
213 PDEVICE_OBJECT DeviceObject,
214 PIRP Irp)
215 {
216 PFDO_DEVICE_EXTENSION DeviceExtension;
217
218 // get common device extension
219 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
220
221 if (DeviceExtension->Common.IsFDO)
222 {
223 PoStartNextPowerIrp(Irp);
224 IoSkipCurrentIrpStackLocation(Irp);
225 return PoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
226 }
227 else
228 {
229 PoStartNextPowerIrp(Irp);
230 Irp->IoStatus.Status = STATUS_SUCCESS;
231 IoCompleteRequest(Irp, IO_NO_INCREMENT);
232 return STATUS_SUCCESS;
233 }
234 }
235
236
237
238 NTSTATUS
239 NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegPath)240 DriverEntry(
241 IN PDRIVER_OBJECT DriverObject,
242 IN PUNICODE_STRING RegPath)
243 {
244
245 DPRINT("********* USB Storage *********\n");
246
247 //
248 // driver unload routine
249 //
250 DriverObject->DriverUnload = USBSTOR_Unload;
251
252 //
253 // add device function
254 //
255 DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice;
256
257 //
258 // driver start i/o routine
259 //
260 DriverObject->DriverStartIo = USBSTOR_StartIo;
261
262 //
263 // create / close
264 //
265 DriverObject->MajorFunction[IRP_MJ_CREATE] = USBSTOR_DispatchClose;
266 DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBSTOR_DispatchClose;
267
268 //
269 // scsi pass through requests
270 //
271 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBSTOR_DispatchDeviceControl;
272
273 //
274 // irp dispatch read / write
275 //
276 DriverObject->MajorFunction[IRP_MJ_READ] = USBSTOR_DispatchReadWrite;
277 DriverObject->MajorFunction[IRP_MJ_WRITE] = USBSTOR_DispatchReadWrite;
278
279 //
280 // scsi queue ioctl
281 //
282 DriverObject->MajorFunction[IRP_MJ_SCSI] = USBSTOR_DispatchScsi;
283
284 //
285 // pnp processing
286 //
287 DriverObject->MajorFunction[IRP_MJ_PNP] = USBSTOR_DispatchPnp;
288
289 //
290 // power processing
291 //
292 DriverObject->MajorFunction[IRP_MJ_POWER] = USBSTOR_DispatchPower;
293
294 return STATUS_SUCCESS;
295 }
296