Skip to content

Commit b558596

Browse files
authored
[SPTILIB] Introduce SPTI static library for storage drivers (reactos#8209)
Add a SCSI and ATA passthrough support helper library for direct use from low-level storage drivers. Tested with: CDRoller, CloneCD, Magic ISO NOTE: Vbox seems to lack support for CD/DVD burning; tested on real hardware. CORE-10191 CORE-16452 CORE-14788 CORE-18241 CORE-17256 CORE-13866
1 parent 5bd84f6 commit b558596

File tree

12 files changed

+1285
-14
lines changed

12 files changed

+1285
-14
lines changed

drivers/storage/port/scsiport/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11

22
spec2def(scsiport.sys scsiport.spec ADD_IMPORTLIB)
33

4+
include_directories(
5+
${REACTOS_SOURCE_DIR}/sdk/lib/drivers/sptilib)
6+
47
# Embed RTC libs
58
if (STACK_PROTECTOR)
69
target_sources(libscsiport PRIVATE $<TARGET_OBJECTS:gcc_ssp_scsiport>)
@@ -27,5 +30,6 @@ add_library(scsiport MODULE
2730

2831
add_pch(scsiport scsiport.h "${PCH_SKIP_SOURCE}")
2932
set_module_type(scsiport kernelmodedriver)
33+
target_link_libraries(scsiport sptilib ${PSEH_LIB})
3034
add_importlibs(scsiport ntoskrnl hal)
3135
add_cd_file(TARGET scsiport DESTINATION reactos/system32/drivers NO_CAB FOR all)

drivers/storage/port/scsiport/ioctl.c

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
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+
291341
static
292342
NTSTATUS
293343
FdoHandleQueryProperty(
@@ -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
}

drivers/storage/port/storport/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11

22
spec2def(storport.sys storport.spec ADD_IMPORTLIB)
33

4+
include_directories(
5+
${REACTOS_SOURCE_DIR}/sdk/lib/drivers/sptilib)
6+
47
list(APPEND SOURCE
58
fdo.c
69
miniport.c
@@ -20,5 +23,6 @@ add_library(storport MODULE
2023

2124
add_pch(storport precomp.h "${PCH_SKIP_SOURCE}")
2225
set_module_type(storport kernelmodedriver)
26+
target_link_libraries(storport sptilib ${PSEH_LIB})
2327
add_importlibs(storport ntoskrnl hal)
2428
add_cd_file(TARGET storport DESTINATION reactos/system32/drivers NO_CAB FOR all)

drivers/usb/usbstor/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11

2+
include_directories(
3+
${REACTOS_SOURCE_DIR}/sdk/lib/drivers/sptilib)
4+
25
list(APPEND SOURCE
36
descriptor.c
47
disk.c
@@ -19,6 +22,7 @@ add_library(usbstor MODULE
1922
usbstor.rc)
2023

2124
set_module_type(usbstor kernelmodedriver)
25+
target_link_libraries(usbstor sptilib ${PSEH_LIB})
2226
add_importlibs(usbstor ntoskrnl hal usbd)
2327
add_pch(usbstor usbstor.h "${PCH_SKIP_SOURCE}")
2428
add_cd_file(TARGET usbstor DESTINATION reactos/system32/drivers NO_CAB FOR all)

drivers/usb/usbstor/disk.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
*/
1010

1111
#include "usbstor.h"
12+
#include <sptilib.h>
1213

1314
#define NDEBUG
1415
#include <debug.h>
1516

17+
// See CORE-10515 and CORE-10755
18+
#define USBSTOR_DEFAULT_MAX_PHYS_PAGES (USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH / PAGE_SIZE + 1)
1619

1720
static
1821
BOOLEAN
@@ -394,7 +397,7 @@ USBSTOR_HandleQueryProperty(
394397
.Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR_WIN8),
395398
.Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR_WIN8),
396399
.MaximumTransferLength = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH,
397-
.MaximumPhysicalPages = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH / PAGE_SIZE + 1, // See CORE-10515 and CORE-10755
400+
.MaximumPhysicalPages = USBSTOR_DEFAULT_MAX_PHYS_PAGES,
398401
.BusType = BusTypeUsb,
399402
.BusMajorVersion = 2, //FIXME verify
400403
.BusMinorVersion = 0 //FIXME
@@ -429,13 +432,27 @@ USBSTOR_HandleDeviceControl(
429432
Status = USBSTOR_HandleQueryProperty(DeviceObject, Irp);
430433
break;
431434
case IOCTL_SCSI_PASS_THROUGH:
432-
DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH NOT implemented\n");
433-
Status = STATUS_NOT_SUPPORTED;
434-
break;
435435
case IOCTL_SCSI_PASS_THROUGH_DIRECT:
436-
DPRINT1("USBSTOR_HandleDeviceControl IOCTL_SCSI_PASS_THROUGH_DIRECT NOT implemented\n");
437-
Status = STATUS_NOT_SUPPORTED;
436+
{
437+
PDODeviceExtension = DeviceObject->DeviceExtension;
438+
439+
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
440+
ASSERT(PDODeviceExtension);
441+
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
442+
443+
/* Skip requests that bypassed the class driver. See also cdrom!RequestHandleScsiPassThrough */
444+
if ((IoGetCurrentIrpStackLocation(Irp)->MinorFunction == 0) && PDODeviceExtension->Claimed)
445+
{
446+
Status = STATUS_INVALID_DEVICE_REQUEST;
447+
break;
448+
}
449+
450+
Status = SptiHandleScsiPassthru(DeviceObject,
451+
Irp,
452+
USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH,
453+
USBSTOR_DEFAULT_MAX_PHYS_PAGES);
438454
break;
455+
}
439456
case IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER:
440457
DPRINT1("USBSTOR_HandleDeviceControl IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER NOT implemented\n");
441458
Status = STATUS_NOT_SUPPORTED;
@@ -461,7 +478,7 @@ USBSTOR_HandleDeviceControl(
461478
if (Capabilities)
462479
{
463480
Capabilities->MaximumTransferLength = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH;
464-
Capabilities->MaximumPhysicalPages = USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH / PAGE_SIZE + 1; // See CORE-10515 and CORE-10755
481+
Capabilities->MaximumPhysicalPages = USBSTOR_DEFAULT_MAX_PHYS_PAGES;
465482
Capabilities->SupportedAsynchronousEvents = 0;
466483
Capabilities->AlignmentMask = 0;
467484
Capabilities->TaggedQueuing = FALSE;

sdk/include/ddk/scsi.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,6 +1886,27 @@ typedef union _CDB {
18861886
UCHAR Streaming:1;
18871887
UCHAR Control;
18881888
} WRITE12;
1889+
struct _ATA_PASSTHROUGH12 {
1890+
UCHAR OperationCode;
1891+
UCHAR Reserved1:1;
1892+
UCHAR Protocol:4;
1893+
UCHAR MultipleCount:3;
1894+
UCHAR TLength:2;
1895+
UCHAR ByteBlock:1;
1896+
UCHAR TDir:1;
1897+
UCHAR Reserved2:1;
1898+
UCHAR CkCond:1;
1899+
UCHAR Offline:2;
1900+
UCHAR Features;
1901+
UCHAR SectorCount;
1902+
UCHAR LbaLow;
1903+
UCHAR LbaMid;
1904+
UCHAR LbaHigh;
1905+
UCHAR Device;
1906+
UCHAR Command;
1907+
UCHAR Reserved3;
1908+
UCHAR Control;
1909+
} ATA_PASSTHROUGH12;
18891910
struct _READ16 {
18901911
UCHAR OperationCode;
18911912
UCHAR Reserved1:3;
@@ -1944,6 +1965,31 @@ typedef union _CDB {
19441965
UCHAR Reserved2:7;
19451966
UCHAR Control;
19461967
} READ_CAPACITY16;
1968+
struct _ATA_PASSTHROUGH16 {
1969+
UCHAR OperationCode;
1970+
UCHAR Extend:1;
1971+
UCHAR Protocol:4;
1972+
UCHAR MultipleCount:3;
1973+
UCHAR TLength:2;
1974+
UCHAR ByteBlock:1;
1975+
UCHAR TDir:1;
1976+
UCHAR Reserved1:1;
1977+
UCHAR CkCond:1;
1978+
UCHAR Offline:2;
1979+
UCHAR Features15_8;
1980+
UCHAR Features7_0;
1981+
UCHAR SectorCount15_8;
1982+
UCHAR SectorCount7_0;
1983+
UCHAR LbaLow15_8;
1984+
UCHAR LbaLow7_0;
1985+
UCHAR LbaMid15_8;
1986+
UCHAR LbaMid7_0;
1987+
UCHAR LbaHigh15_8;
1988+
UCHAR LbaHigh7_0;
1989+
UCHAR Device;
1990+
UCHAR Command;
1991+
UCHAR Control;
1992+
} ATA_PASSTHROUGH16;
19471993
struct _TOKEN_OPERATION {
19481994
UCHAR OperationCode;
19491995
UCHAR ServiceAction:5;

sdk/include/psdk/ntddscsi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ typedef struct _SCSI_PASS_THROUGH_DIRECT32_EX
256256
#define ATA_FLAGS_DATA_OUT (1 << 2)
257257
#define ATA_FLAGS_48BIT_COMMAND (1 << 3)
258258
#define ATA_FLAGS_USE_DMA (1 << 4)
259+
#define ATA_FLAGS_NO_MULTIPLE (1 << 5)
259260

260261
typedef struct _SCSI_BUS_DATA {
261262
UCHAR NumberOfLogicalUnits;

sdk/lib/drivers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ add_subdirectory(rdbsslib)
99
add_subdirectory(rtlver)
1010
add_subdirectory(rxce)
1111
add_subdirectory(sound)
12+
add_subdirectory(sptilib)
1213
add_subdirectory(virtio)
1314
add_subdirectory(wdf)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
list(APPEND SOURCE
3+
sptilib.c)
4+
5+
add_library(sptilib ${SOURCE})
6+
target_link_libraries(sptilib PRIVATE ${PSEH_LIB})
7+
add_dependencies(sptilib xdk)

0 commit comments

Comments
 (0)