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