0076c519d38bbb8085b9ed3e0361c9e6091ec30b
[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 IoInitializeTimer(DeviceObject, USBSTOR_TimerRoutine, (PVOID)DeviceExtension);
44
45 // did attaching fail
46 if (!DeviceExtension->LowerDeviceObject)
47 {
48 IoDeleteDevice(DeviceObject);
49
50 return STATUS_DEVICE_REMOVED;
51 }
52
53 DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
54
55 // device is initialized
56 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
57
58 return STATUS_SUCCESS;
59 }
60
61 VOID
62 NTAPI
63 USBSTOR_Unload(
64 PDRIVER_OBJECT DriverObject)
65 {
66 // no-op
67 }
68
69 NTSTATUS
70 NTAPI
71 USBSTOR_DispatchClose(
72 PDEVICE_OBJECT DeviceObject,
73 PIRP Irp)
74 {
75 // function always succeeds ;)
76 DPRINT("USBSTOR_DispatchClose\n");
77 Irp->IoStatus.Information = 0;
78 Irp->IoStatus.Status = STATUS_SUCCESS;
79 IoCompleteRequest(Irp, IO_NO_INCREMENT);
80 return STATUS_SUCCESS;
81 }
82
83 NTSTATUS
84 NTAPI
85 USBSTOR_DispatchDeviceControl(
86 PDEVICE_OBJECT DeviceObject,
87 PIRP Irp)
88 {
89 NTSTATUS Status;
90
91 Status = USBSTOR_HandleDeviceControl(DeviceObject, Irp);
92 Irp->IoStatus.Status = Status;
93 IoCompleteRequest(Irp, IO_NO_INCREMENT);
94 return Status;
95 }
96
97 NTSTATUS
98 NTAPI
99 USBSTOR_DispatchScsi(
100 PDEVICE_OBJECT DeviceObject,
101 PIRP Irp)
102 {
103 return USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
104 }
105
106 NTSTATUS
107 NTAPI
108 USBSTOR_DispatchReadWrite(
109 PDEVICE_OBJECT DeviceObject,
110 PIRP Irp)
111 {
112 // read write ioctl is not supported
113 Irp->IoStatus.Information = 0;
114 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
115 IoCompleteRequest(Irp, IO_NO_INCREMENT);
116 return STATUS_INVALID_PARAMETER;
117 }
118
119 NTSTATUS
120 NTAPI
121 USBSTOR_DispatchPnp(
122 PDEVICE_OBJECT DeviceObject,
123 PIRP Irp)
124 {
125 PUSBSTOR_COMMON_DEVICE_EXTENSION DeviceExtension;
126
127 DeviceExtension = (PUSBSTOR_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
128
129 if (DeviceExtension->IsFDO)
130 {
131 return USBSTOR_FdoHandlePnp(DeviceObject, Irp);
132 }
133 else
134 {
135 return USBSTOR_PdoHandlePnp(DeviceObject, Irp);
136 }
137 }
138
139 NTSTATUS
140 NTAPI
141 USBSTOR_DispatchPower(
142 PDEVICE_OBJECT DeviceObject,
143 PIRP Irp)
144 {
145 PFDO_DEVICE_EXTENSION DeviceExtension;
146
147 // get common device extension
148 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
149
150 if (DeviceExtension->Common.IsFDO)
151 {
152 PoStartNextPowerIrp(Irp);
153 IoSkipCurrentIrpStackLocation(Irp);
154 return PoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
155 }
156 else
157 {
158 PoStartNextPowerIrp(Irp);
159 Irp->IoStatus.Status = STATUS_SUCCESS;
160 IoCompleteRequest(Irp, IO_NO_INCREMENT);
161 return STATUS_SUCCESS;
162 }
163 }
164
165 NTSTATUS
166 NTAPI
167 DriverEntry(
168 IN PDRIVER_OBJECT DriverObject,
169 IN PUNICODE_STRING RegPath)
170 {
171
172 DPRINT("********* USB Storage *********\n");
173
174 DriverObject->DriverUnload = USBSTOR_Unload;
175 DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice;
176 DriverObject->DriverStartIo = USBSTOR_StartIo;
177 DriverObject->MajorFunction[IRP_MJ_CREATE] = USBSTOR_DispatchClose;
178 DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBSTOR_DispatchClose;
179 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBSTOR_DispatchDeviceControl; // scsi pass through requests
180 DriverObject->MajorFunction[IRP_MJ_READ] = USBSTOR_DispatchReadWrite;
181 DriverObject->MajorFunction[IRP_MJ_WRITE] = USBSTOR_DispatchReadWrite;
182 DriverObject->MajorFunction[IRP_MJ_SCSI] = USBSTOR_DispatchScsi;
183 DriverObject->MajorFunction[IRP_MJ_PNP] = USBSTOR_DispatchPnp;
184 DriverObject->MajorFunction[IRP_MJ_POWER] = USBSTOR_DispatchPower;
185
186 return STATUS_SUCCESS;
187 }