88 */
99
1010#include "scsiport.h"
11+ #include <sptilib.h>
1112
1213#define NDEBUG
1314#include <debug.h>
@@ -276,7 +277,6 @@ PdoHandleQueryProperty(
276277 }
277278 default :
278279 {
279- UNREACHABLE ;
280280 status = STATUS_NOT_IMPLEMENTED ;
281281 goto completeIrp ;
282282 }
@@ -288,6 +288,56 @@ PdoHandleQueryProperty(
288288 return status ;
289289}
290290
291+ static
292+ NTSTATUS
293+ PdoHandleScsiPassthrough (
294+ _In_ PDEVICE_OBJECT DeviceObject ,
295+ _Inout_ PIRP Irp )
296+ {
297+ PSCSI_PORT_LUN_EXTENSION lunExt = DeviceObject -> DeviceExtension ;
298+ PSCSI_PORT_DEVICE_EXTENSION portExt ;
299+
300+ ASSERT (KeGetCurrentIrql () < DISPATCH_LEVEL );
301+ ASSERT (!lunExt -> Common .IsFDO );
302+
303+ /* Skip requests that bypassed the class driver. See also cdrom!RequestHandleScsiPassThrough */
304+ if ((IoGetCurrentIrpStackLocation (Irp )-> MinorFunction == 0 ) && lunExt -> DeviceClaimed )
305+ return STATUS_INVALID_DEVICE_REQUEST ;
306+
307+ portExt = lunExt -> Common .LowerDevice -> DeviceExtension ;
308+
309+ return SptiHandleScsiPassthru (DeviceObject ,
310+ Irp ,
311+ portExt -> PortCapabilities .MaximumTransferLength ,
312+ portExt -> PortCapabilities .MaximumPhysicalPages );
313+ }
314+
315+ static
316+ NTSTATUS
317+ FdoHandleScsiPassthrough (
318+ _In_ PDEVICE_OBJECT DeviceObject ,
319+ _Inout_ PIRP Irp )
320+ {
321+ PSCSI_PORT_DEVICE_EXTENSION portExt ;
322+ PSCSI_PORT_LUN_EXTENSION lunExt ;
323+ PSCSI_PASS_THROUGH spt ;
324+
325+ ASSERT (KeGetCurrentIrql () < DISPATCH_LEVEL );
326+
327+ if (!VerifyIrpInBufferSize (Irp , RTL_SIZEOF_THROUGH_FIELD (SCSI_PASS_THROUGH , Lun )))
328+ return STATUS_BUFFER_TOO_SMALL ;
329+
330+ portExt = DeviceObject -> DeviceExtension ;
331+ ASSERT (portExt -> Common .IsFDO );
332+
333+ spt = Irp -> AssociatedIrp .SystemBuffer ;
334+ lunExt = GetLunByPath (portExt , spt -> PathId , spt -> TargetId , spt -> Lun );
335+ if (!lunExt )
336+ return STATUS_NO_SUCH_DEVICE ;
337+
338+ return PdoHandleScsiPassthrough (lunExt -> Common .DeviceObject , Irp );
339+ }
340+
291341static
292342NTSTATUS
293343FdoHandleQueryProperty (
@@ -409,15 +459,17 @@ ScsiPortDeviceControl(
409459 PSCSI_PORT_COMMON_EXTENSION comExt = DeviceObject -> DeviceExtension ;
410460 PSCSI_PORT_DEVICE_EXTENSION portExt ;
411461 PSCSI_PORT_LUN_EXTENSION lunExt ;
462+ ULONG IoControlCode ;
412463 NTSTATUS status ;
413464
414465 DPRINT ("ScsiPortDeviceControl()\n" );
415466
416467 Irp -> IoStatus .Information = 0 ;
417468
418469 Stack = IoGetCurrentIrpStackLocation (Irp );
470+ IoControlCode = Stack -> Parameters .DeviceIoControl .IoControlCode ;
419471
420- switch (Stack -> Parameters . DeviceIoControl . IoControlCode )
472+ switch (IoControlCode )
421473 {
422474 case IOCTL_STORAGE_QUERY_PROPERTY :
423475 {
@@ -534,20 +586,27 @@ ScsiPortDeviceControl(
534586 break ;
535587
536588 case IOCTL_SCSI_PASS_THROUGH :
537- DPRINT1 ("IOCTL_SCSI_PASS_THROUGH unimplemented!\n" );
538- status = STATUS_NOT_IMPLEMENTED ;
589+ case IOCTL_SCSI_PASS_THROUGH_DIRECT :
590+ {
591+ DPRINT (" IOCTL_SCSI_PASS_THROUGH%s\n" ,
592+ IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT ? "_DIRECT" : "" );
593+
594+ if (comExt -> IsFDO )
595+ status = FdoHandleScsiPassthrough (DeviceObject , Irp );
596+ else
597+ status = PdoHandleScsiPassthrough (DeviceObject , Irp );
539598 break ;
599+ }
540600
541601 case IOCTL_ATA_PASS_THROUGH :
542602 case IOCTL_ATA_PASS_THROUGH_DIRECT :
543603 /* ATA passthrough IOCTLs not supported by MS scsiport */
544- DPRINT1 ("ATA passthrough IOCTLs not supported: 0x%lX\n" ,
545- Stack -> Parameters .DeviceIoControl .IoControlCode );
604+ DPRINT1 ("ATA passthrough IOCTLs not supported: 0x%lX\n" , IoControlCode );
546605 status = STATUS_NOT_SUPPORTED ;
547606 break ;
548607
549608 default :
550- DPRINT1 ("unknown ioctl code: 0x%lX\n" , Stack -> Parameters . DeviceIoControl . IoControlCode );
609+ DPRINT1 ("unknown ioctl code: 0x%lX\n" , IoControlCode );
551610 status = STATUS_NOT_SUPPORTED ;
552611 break ;
553612 }
0 commit comments