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 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 100 USBSTOR_Unload( 101 PDRIVER_OBJECT DriverObject) 102 { 103 // 104 // no-op 105 // 106 } 107 108 NTSTATUS 109 NTAPI 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 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 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 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 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 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 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