1 2 #pragma once 3 4 #include <ntddk.h> 5 #define YDEBUG 6 #include <debug.h> 7 #include <usbdi.h> 8 #include <hubbusif.h> 9 #include <usbbusif.h> 10 #include <usbioctl.h> 11 #include <usbiodef.h> 12 #include <usb.h> 13 #include <usbdlib.h> 14 #include <stdio.h> 15 #include <wdmguid.h> 16 #include <classpnp.h> 17 #include <scsi.h> 18 19 #define USB_STOR_TAG 'sbsu' 20 #define USB_MAXCHILDREN (16) 21 22 23 24 #define HTONS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8)) 25 #define NTOHS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8)) 26 27 #define HTONL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \ 28 ((((unsigned long)(n) & 0xFF00)) << 8) | \ 29 ((((unsigned long)(n) & 0xFF0000)) >> 8) | \ 30 ((((unsigned long)(n) & 0xFF000000)) >> 24)) 31 32 33 #define NTOHL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \ 34 ((((unsigned long)(n) & 0xFF00)) << 8) | \ 35 ((((unsigned long)(n) & 0xFF0000)) >> 8) | \ 36 ((((unsigned long)(n) & 0xFF000000)) >> 24)) 37 38 #define USB_RECOVERABLE_ERRORS (USBD_STATUS_STALL_PID | USBD_STATUS_DEV_NOT_RESPONDING \ 39 | USBD_STATUS_ENDPOINT_HALTED | USBD_STATUS_NO_BANDWIDTH) 40 41 typedef struct __COMMON_DEVICE_EXTENSION__ 42 { 43 BOOLEAN IsFDO; 44 45 }USBSTOR_COMMON_DEVICE_EXTENSION, *PUSBSTOR_COMMON_DEVICE_EXTENSION; 46 47 typedef struct 48 { 49 USBSTOR_COMMON_DEVICE_EXTENSION Common; // common device extension 50 51 PDEVICE_OBJECT FunctionalDeviceObject; // functional device object 52 PDEVICE_OBJECT PhysicalDeviceObject; // physical device object 53 PDEVICE_OBJECT LowerDeviceObject; // lower device object 54 USB_BUS_INTERFACE_USBDI_V2 BusInterface; // bus interface of device 55 PUSB_DEVICE_DESCRIPTOR DeviceDescriptor; // usb device descriptor 56 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; // usb configuration descriptor 57 PUSB_STRING_DESCRIPTOR SerialNumber; // usb serial number 58 PUSBD_INTERFACE_INFORMATION InterfaceInformation; // usb interface information 59 USBD_CONFIGURATION_HANDLE ConfigurationHandle; // usb configuration handle 60 UCHAR BulkInPipeIndex; // bulk in pipe index 61 UCHAR BulkOutPipeIndex; // bulk out pipe index 62 UCHAR MaxLUN; // max lun for device 63 PDEVICE_OBJECT ChildPDO[16]; // max 16 child pdo devices 64 KSPIN_LOCK IrpListLock; // irp list lock 65 LIST_ENTRY IrpListHead; // irp list head 66 BOOLEAN IrpListFreeze; // if true the irp list is freezed 67 BOOLEAN ResetInProgress; // if hard reset is in progress 68 ULONG IrpPendingCount; // count of irp pending 69 PSCSI_REQUEST_BLOCK ActiveSrb; // stores the current active SRB 70 KEVENT NoPendingRequests; // set if no pending or in progress requests 71 }FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; 72 73 typedef struct 74 { 75 USBSTOR_COMMON_DEVICE_EXTENSION Common; 76 PDEVICE_OBJECT LowerDeviceObject; // points to FDO 77 UCHAR LUN; // lun id 78 PVOID InquiryData; // USB SCSI inquiry data 79 UCHAR Claimed; // indicating if it has been claimed by upper driver 80 ULONG BlockLength; // length of block 81 ULONG LastLogicBlockAddress; // last block address 82 PDEVICE_OBJECT *PDODeviceObject; // entry in pdo list 83 }PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION; 84 85 // 86 // max lun command identifier 87 // 88 #define USB_BULK_GET_MAX_LUN 0xFE 89 #define USB_BULK_RESET_DEVICE 0xFF 90 91 #include <pshpack1.h> 92 typedef struct 93 { 94 ULONG Signature; // CBW signature 95 ULONG Tag; // CBW Tag of operation 96 ULONG DataTransferLength; // data transfer length 97 UCHAR Flags; // CBW Flags endpoint direction 98 UCHAR LUN; // lun unit 99 UCHAR CommandBlockLength; // Command block length 100 UCHAR CommandBlock[16]; 101 }CBW, *PCBW; 102 103 C_ASSERT(sizeof(CBW) == 31); 104 105 106 #define CBW_SIGNATURE 0x43425355 107 #define CSW_SIGNATURE 0x53425355 108 109 #define MAX_LUN 0xF 110 111 typedef struct 112 { 113 ULONG Signature; // CSW signature 114 ULONG Tag; // CSW tag 115 ULONG DataResidue; // CSW data transfer diff 116 UCHAR Status; // CSW status 117 }CSW, *PCSW; 118 119 //-------------------------------------------------------------------------------------------------------------------------------------------- 120 // 121 // UFI INQUIRY command 122 // 123 typedef struct 124 { 125 UCHAR Code; // operation code 0x12 126 UCHAR LUN; // lun address 127 UCHAR PageCode; // product data information, always 0x00 128 UCHAR Reserved; // reserved 0x00 129 UCHAR AllocationLength; // length of inquiry data to be returned, default 36 bytes 130 UCHAR Reserved1[7]; //reserved bytes 0x00 131 }UFI_INQUIRY_CMD, *PUFI_INQUIRY_CMD; 132 133 C_ASSERT(sizeof(UFI_INQUIRY_CMD) == 12); 134 135 #define UFI_INQUIRY_CMD_LEN 0x6 136 137 // 138 // UFI INQUIRY command response 139 // 140 typedef struct 141 { 142 UCHAR DeviceType; // device type 143 UCHAR RMB; // removable media bit 144 UCHAR Version; // contains version 0x00 145 UCHAR Format; // response format 146 UCHAR Length; // additional length 147 UCHAR Reserved[3]; // reserved 148 UCHAR Vendor[8]; // vendor identification string 149 UCHAR Product[16]; // product identification string 150 UCHAR Revision[4]; // product revision code 151 }UFI_INQUIRY_RESPONSE, *PUFI_INQUIRY_RESPONSE; 152 153 C_ASSERT(sizeof(UFI_INQUIRY_RESPONSE) == 36); 154 155 //-------------------------------------------------------------------------------------------------------------------------------------------- 156 // 157 // UFI read cmd 158 // 159 typedef struct 160 { 161 UCHAR Code; // operation code 162 UCHAR LUN; // lun 163 UCHAR LogicalBlockByte0; // lba byte 0 164 UCHAR LogicalBlockByte1; // lba byte 1 165 UCHAR LogicalBlockByte2; // lba byte 2 166 UCHAR LogicalBlockByte3; // lba byte 3 167 UCHAR Reserved; // reserved 0x00 168 UCHAR ContiguousLogicBlocksByte0; // msb contigious logic blocks byte 169 UCHAR ContiguousLogicBlocksByte1; // msb contigious logic blocks 170 UCHAR Reserved1[3]; // reserved 0x00 171 }UFI_READ_WRITE_CMD; 172 173 C_ASSERT(sizeof(UFI_READ_WRITE_CMD) == 12); 174 175 #define UFI_READ_WRITE_CMD_LEN (0xA) 176 177 //-------------------------------------------------------------------------------------------------------------------------------------------- 178 // 179 // UFI read capacity cmd 180 // 181 typedef struct 182 { 183 UCHAR Code; // operation code 0x25 184 UCHAR LUN; // lun address 185 UCHAR LBA[4]; // logical block address, should be zero 186 UCHAR Reserved1[2]; // reserved 0x00 187 UCHAR PMI; // PMI = 0x00 188 UCHAR Reserved2[3]; // reserved 0x00 189 }UFI_CAPACITY_CMD, *PUFI_CAPACITY_CMD; 190 191 C_ASSERT(sizeof(UFI_CAPACITY_CMD) == 12); 192 193 #define UFI_CAPACITY_CMD_LEN 0xA //FIXME support length 16 too if requested 194 195 // 196 // UFI Read Capcacity command response 197 // 198 typedef struct 199 { 200 ULONG LastLogicalBlockAddress; // last logical block address 201 ULONG BlockLength; // block length in bytes 202 }UFI_CAPACITY_RESPONSE, *PUFI_CAPACITY_RESPONSE; 203 204 #define UFI_READ_CAPACITY_CMD_LEN 0xA 205 C_ASSERT(sizeof(UFI_CAPACITY_RESPONSE) == 8); 206 207 //-------------------------------------------------------------------------------------------------------------------------------------------- 208 // 209 // UFI sense mode cmd 210 // 211 typedef struct 212 { 213 UCHAR Code; // operation code 214 UCHAR LUN; // lun address 215 UCHAR PageCode:6; // page code selector 216 UCHAR PC:2; // type of parameters to be returned 217 UCHAR Reserved[4]; // reserved 0x00 218 USHORT AllocationLength; // parameters length 219 UCHAR Reserved1[3]; 220 }UFI_SENSE_CMD, *PUFI_SENSE_CMD; 221 222 C_ASSERT(sizeof(UFI_SENSE_CMD) == 12); 223 224 #define UFI_SENSE_CMD_LEN (6) 225 226 typedef struct 227 { 228 USHORT ModeDataLength; // length of parameters for sense cmd 229 UCHAR MediumTypeCode; // 00 for mass storage, 0x94 for floppy 230 UCHAR WP:1; // write protect bit 231 UCHAR Reserved1:2; // reserved 00 232 UCHAR DPOFUA:1; // should be zero 233 UCHAR Reserved2:4; // reserved 234 UCHAR Reserved[4]; // reserved 235 }UFI_MODE_PARAMETER_HEADER, *PUFI_MODE_PARAMETER_HEADER; 236 237 238 C_ASSERT(sizeof(UFI_MODE_PARAMETER_HEADER) == 8); 239 240 typedef struct 241 { 242 UCHAR PC; 243 UCHAR PageLength; 244 UCHAR Reserved1; 245 UCHAR ITM; 246 UCHAR Flags; 247 UCHAR Reserved[3]; 248 }UFI_TIMER_PROTECT_PAGE, *PUFI_TIMER_PROTECT_PAGE; 249 C_ASSERT(sizeof(UFI_TIMER_PROTECT_PAGE) == 8); 250 251 //-------------------------------------------------------------------------------------------------------------------------------------------- 252 // 253 // UFI test unit command 254 // 255 256 typedef struct 257 { 258 UCHAR Code; // operation code 0x00 259 UCHAR LUN; // lun 260 UCHAR Reserved[10]; // reserved 0x00 261 }UFI_TEST_UNIT_CMD, *PUFI_TEST_UNIT_CMD; 262 263 C_ASSERT(sizeof(UFI_TEST_UNIT_CMD) == 12); 264 265 #define UFI_TEST_UNIT_CMD_LEN (6) 266 267 typedef struct 268 { 269 union 270 { 271 PCBW cbw; 272 PCSW csw; 273 }; 274 URB Urb; 275 PIRP Irp; 276 ULONG TransferDataLength; 277 PUCHAR TransferData; 278 PFDO_DEVICE_EXTENSION FDODeviceExtension; 279 PPDO_DEVICE_EXTENSION PDODeviceExtension; 280 PMDL TransferBufferMDL; 281 PKEVENT Event; 282 }IRP_CONTEXT, *PIRP_CONTEXT; 283 284 typedef struct _ERRORHANDLER_WORKITEM_DATA 285 { 286 PDEVICE_OBJECT DeviceObject; 287 PIRP_CONTEXT Context; 288 WORK_QUEUE_ITEM WorkQueueItem; 289 } ERRORHANDLER_WORKITEM_DATA, *PERRORHANDLER_WORKITEM_DATA; 290 291 292 //--------------------------------------------------------------------- 293 // 294 // fdo.c routines 295 // 296 NTSTATUS 297 USBSTOR_FdoHandlePnp( 298 IN PDEVICE_OBJECT DeviceObject, 299 IN OUT PIRP Irp); 300 301 //--------------------------------------------------------------------- 302 // 303 // pdo.c routines 304 // 305 NTSTATUS 306 USBSTOR_PdoHandlePnp( 307 IN PDEVICE_OBJECT DeviceObject, 308 IN OUT PIRP Irp); 309 310 NTSTATUS 311 USBSTOR_CreatePDO( 312 IN PDEVICE_OBJECT DeviceObject, 313 OUT PDEVICE_OBJECT *ChildDeviceObject); 314 315 //--------------------------------------------------------------------- 316 // 317 // misc.c routines 318 // 319 NTSTATUS 320 NTAPI 321 USBSTOR_SyncForwardIrp( 322 IN PDEVICE_OBJECT DeviceObject, 323 IN OUT PIRP Irp); 324 325 NTSTATUS 326 NTAPI 327 USBSTOR_GetBusInterface( 328 IN PDEVICE_OBJECT DeviceObject, 329 OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface); 330 331 PVOID 332 AllocateItem( 333 IN POOL_TYPE PoolType, 334 IN ULONG ItemSize); 335 336 VOID 337 FreeItem( 338 IN PVOID Item); 339 340 NTSTATUS 341 USBSTOR_SyncUrbRequest( 342 IN PDEVICE_OBJECT DeviceObject, 343 OUT PURB UrbRequest); 344 345 NTSTATUS 346 USBSTOR_GetMaxLUN( 347 IN PDEVICE_OBJECT DeviceObject, 348 IN PFDO_DEVICE_EXTENSION DeviceExtension); 349 350 NTSTATUS 351 NTAPI 352 USBSTOR_SyncForwardIrpCompletionRoutine( 353 PDEVICE_OBJECT DeviceObject, 354 PIRP Irp, 355 PVOID Context); 356 357 NTSTATUS 358 USBSTOR_ResetDevice( 359 IN PDEVICE_OBJECT DeviceObject, 360 IN PFDO_DEVICE_EXTENSION DeviceExtension); 361 362 //--------------------------------------------------------------------- 363 // 364 // descriptor.c routines 365 // 366 367 NTSTATUS 368 USBSTOR_GetDescriptors( 369 IN PDEVICE_OBJECT DeviceObject); 370 371 NTSTATUS 372 USBSTOR_SelectConfigurationAndInterface( 373 IN PDEVICE_OBJECT DeviceObject, 374 IN PFDO_DEVICE_EXTENSION DeviceExtension); 375 376 NTSTATUS 377 USBSTOR_GetPipeHandles( 378 IN PFDO_DEVICE_EXTENSION DeviceExtension); 379 380 //--------------------------------------------------------------------- 381 // 382 // scsi.c routines 383 // 384 NTSTATUS 385 USBSTOR_HandleExecuteSCSI( 386 IN PDEVICE_OBJECT DeviceObject, 387 IN PIRP Irp); 388 389 NTSTATUS 390 USBSTOR_SendInquiryCmd( 391 IN PDEVICE_OBJECT DeviceObject); 392 393 //--------------------------------------------------------------------- 394 // 395 // disk.c routines 396 // 397 NTSTATUS 398 USBSTOR_HandleInternalDeviceControl( 399 IN PDEVICE_OBJECT DeviceObject, 400 IN PIRP Irp); 401 402 NTSTATUS 403 USBSTOR_HandleDeviceControl( 404 IN PDEVICE_OBJECT DeviceObject, 405 IN PIRP Irp); 406 407 //--------------------------------------------------------------------- 408 // 409 // queue.c routines 410 // 411 VOID 412 NTAPI 413 USBSTOR_StartIo( 414 PDEVICE_OBJECT DeviceObject, 415 PIRP Irp); 416 417 VOID 418 USBSTOR_QueueWaitForPendingRequests( 419 IN PDEVICE_OBJECT DeviceObject); 420 421 VOID 422 USBSTOR_QueueRelease( 423 IN PDEVICE_OBJECT DeviceObject); 424 425 BOOLEAN 426 USBSTOR_QueueAddIrp( 427 IN PDEVICE_OBJECT DeviceObject, 428 IN PIRP Irp); 429 430 VOID 431 NTAPI 432 USBSTOR_CancelIo( 433 IN PDEVICE_OBJECT DeviceObject, 434 IN PIRP Irp); 435 436 VOID 437 USBSTOR_QueueInitialize( 438 PFDO_DEVICE_EXTENSION FDODeviceExtension); 439 440 VOID 441 NTAPI 442 ErrorHandlerWorkItemRoutine( 443 PVOID Context); 444 445 VOID 446 USBSTOR_QueueNextRequest( 447 IN PDEVICE_OBJECT DeviceObject); 448 449 VOID 450 USBSTOR_QueueTerminateRequest( 451 IN PDEVICE_OBJECT DeviceObject, 452 IN PIRP Irp); 453 454 /* error.c */ 455 NTSTATUS 456 USBSTOR_GetEndpointStatus( 457 IN PDEVICE_OBJECT DeviceObject, 458 IN UCHAR bEndpointAddress, 459 OUT PUSHORT Value); 460 461