xref: /reactos/drivers/usb/usbstor/usbstor.c (revision 9393fc32)
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 }
210