typedef void VOID; typedef char CHAR; typedef long LONG; typedef unsigned long ULONG; typedef unsigned short USHORT; typedef unsigned char UCHAR; typedef UCHAR BOOLEAN; struct LARGE_INTEGER { ULONG LowPart; LONG HighPart; }; typedef LARGE_INTEGER SCSI_PHYSICAL_ADDRESS; typedef VOID* PVOID; typedef BOOLEAN* PBOOLEAN; typedef CHAR* PCHAR; #define IN #define OUT #define NULL 0 enum { FALSE, TRUE }; static const UCHAR SP_UNTAGGED = (UCHAR)~0; enum INTERFACE_TYPE { InterfaceTypeUndefined = -1, Internal, Isa, Eisa, MicroChannel, TurboChannel, PCIBus, VMEBus, NuBus, PCMCIABus, CBus, MPIBus, MPSABus, ProcessorInternal, InternalPowerBus, PNPISABus, PNPBus, MaximumInterfaceType }; enum SCSI_NOTIFICATION_TYPE { RequestComplete, NextRequest, NextLuRequest, ResetDetected, CallDisableInterrupts, CallEnableInterrupts, RequestTimerCall, BusChangeDetected, WMIEvent, WMIReregister }; enum SCSI_ADAPTER_CONTROL_TYPE { ScsiQuerySupportedControlTypes, ScsiStopAdapter, ScsiRestartAdapter, ScsiSetBootConfig, ScsiSetRunningConfig, ScsiAdapterControlMax, MakeAdapterControlTypeSizeOfUlong = 0xffffffff }; enum SCSI_ADAPTER_CONTROL_STATUS { ScsiAdapterControlSuccess, ScsiAdapterControlUnsuccessful }; enum KINTERRUPT_MODE { LevelSensitive, Latched }; enum DMA_WIDTH { Width8Bits, Width16Bits, Width32Bits, MaximumDmaWidth }; enum DMA_SPEED { Compatible, TypeA, TypeB, TypeC, TypeF, MaximumDmaSpeed }; struct ACCESS_RANGE { SCSI_PHYSICAL_ADDRESS RangeStart; ULONG RangeLength; BOOLEAN RangeInMemory; }; struct SCSI_REQUEST_BLOCK { USHORT Length; UCHAR Function; UCHAR SrbStatus; UCHAR ScsiStatus; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR QueueTag; UCHAR QueueAction; UCHAR CdbLength; UCHAR SenseInfoBufferLength; ULONG SrbFlags; ULONG DataTransferLength; ULONG TimeOutValue; PVOID DataBuffer; PVOID SenseInfoBuffer; SCSI_REQUEST_BLOCK* NextSrb; PVOID OriginalRequest; PVOID SrbExtension; union { ULONG InternalStatus; ULONG QueueSortKey; }; #if defined(_WIN64) ULONG Reserved; #endif UCHAR Cdb[16]; // offset 30 }; typedef SCSI_REQUEST_BLOCK* PSCSI_REQUEST_BLOCK; struct PORT_CONFIGURATION_INFORMATION { ULONG Length; ULONG SystemIoBusNumber; INTERFACE_TYPE AdapterInterfaceType; ULONG BusInterruptLevel; ULONG BusInterruptVector; KINTERRUPT_MODE InterruptMode; ULONG MaximumTransferLength; ULONG NumberOfPhysicalBreaks; ULONG DmaChannel; ULONG DmaPort; DMA_WIDTH DmaWidth; DMA_SPEED DmaSpeed; ULONG AlignmentMask; ULONG NumberOfAccessRanges; ACCESS_RANGE (*AccessRanges)[]; PVOID Reserved; UCHAR NumberOfBuses; UCHAR InitiatorBusId[8]; BOOLEAN ScatterGather; BOOLEAN Master; BOOLEAN CachesData; BOOLEAN AdapterScansDown; BOOLEAN AtdiskPrimaryClaimed; BOOLEAN AtdiskSecondaryClaimed; BOOLEAN Dma32BitAddresses; BOOLEAN DemandMode; BOOLEAN MapBuffers; BOOLEAN NeedPhysicalAddresses; BOOLEAN TaggedQueuing; BOOLEAN AutoRequestSense; BOOLEAN MultipleRequestPerLu; BOOLEAN ReceiveEvent; BOOLEAN RealModeInitialized; BOOLEAN BufferAccessScsiPortControlled; UCHAR MaximumNumberOfTargets; UCHAR ReservedUchars[2]; ULONG SlotNumber; ULONG BusInterruptLevel2; ULONG BusInterrutVector2; KINTERRUPT_MODE InterruptMode2; ULONG DmaChannel2; ULONG DmaPort2; DMA_WIDTH DmaWidth2; DMA_SPEED DmaSpeed2; ULONG DeviceExtensionSize; ULONG SpecificLuExtensionSize; ULONG SrbExtensionSize; UCHAR Dma64BitAddresses; BOOLEAN ResetTargetSupported; UCHAR MaximumNumberOfLogicalUnits; BOOLEAN WmiDataProvider; }; typedef PORT_CONFIGURATION_INFORMATION* PPORT_CONFIGURATION_INFORMATION; struct SCSI_SUPPORTED_CONTROL_TYPE_LIST { IN ULONG MaxControlType; OUT BOOLEAN SupportedTypeList[ScsiAdapterControlMax]; }; #define SP_RETURN_NOT_FOUND 0 #define SP_RETURN_FOUND 1 #define SP_RETURN_ERROR 2 #define SP_RETURN_BAD_CONFIG 3 typedef BOOLEAN (__stdcall *PHW_INITIALIZE)(IN PVOID DeviceExtension); typedef BOOLEAN (__stdcall *PHW_STARTIO)(IN PVOID DeviceExtension, IN SCSI_REQUEST_BLOCK* Srb); typedef BOOLEAN (__stdcall *PHW_INTERRUPT)(IN PVOID DeviceExtension); typedef VOID (__stdcall *PHW_TIMER)(IN PVOID DeviceExtension); typedef VOID (__stdcall *PHW_DMA_STARTED)(IN PVOID DeviceExtension); typedef ULONG (__stdcall *PHW_FIND_ADAPTER)(IN PVOID DeviceExtension, IN PVOID HwContext, IN PVOID BusInformation, IN CHAR* ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again); typedef BOOLEAN (__stdcall *PHW_RESET_BUS)(IN PVOID DeviceExtension, IN ULONG PathId); typedef BOOLEAN (__stdcall *PHW_ADAPTER_STATE)(IN PVOID DeviceExtension, IN PVOID Context, IN BOOLEAN SaveState); typedef SCSI_ADAPTER_CONTROL_STATUS (__stdcall *PHW_ADAPTER_CONTROL)(IN PVOID DeviceExtension, IN SCSI_ADAPTER_CONTROL_TYPE ControlType, IN PVOID Parameters); struct HW_INITIALIZATION_DATA { ULONG HwInitializationDataSize; INTERFACE_TYPE AdapterInterfaceType; PHW_INITIALIZE HwInitialize; PHW_STARTIO HwStartIo; PHW_INTERRUPT HwInterrupt; PHW_FIND_ADAPTER HwFindAdapter; PHW_RESET_BUS HwResetBus; PHW_DMA_STARTED HwDmaStarted; PHW_ADAPTER_STATE HwAdapterState; ULONG DeviceExtensionSize; ULONG SpecificLuExtensionSize; ULONG SrbExtensionSize; ULONG NumberOfAccessRanges; PVOID Reserved; BOOLEAN MapBuffers; BOOLEAN NeedPhysicalAddresses; BOOLEAN TaggedQueuing; BOOLEAN AutoRequestSense; BOOLEAN MultipleRequestPerLu; BOOLEAN ReceiveEvent; USHORT VendorIdLength; PVOID VendorId; USHORT ReservedUshort; USHORT DeviceIdLength; PVOID DeviceId; PHW_ADAPTER_CONTROL HwAdapterControl; }; extern "C" { ULONG __stdcall ScsiPortInitialize(IN VOID* Argument1, IN VOID* Argument2, IN HW_INITIALIZATION_DATA* HwInitializationData, IN VOID* HwContext); VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN VOID* HwDeviceExtension, ...); VOID __stdcall ScsiPortLogError(IN VOID* HwDeviceExtension, IN SCSI_REQUEST_BLOCK* Srb, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN ULONG ErrorCode, IN ULONG UniqueId); VOID __stdcall ScsiPortCompleteRequest(IN VOID* HwDeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN UCHAR SrbStatus); VOID __stdcall ScsiPortMoveMemory(IN VOID* WriteBuffer, IN VOID* ReadBuffer, IN ULONG Length); VOID __cdecl ScsiDebugPrint(ULONG DebugPrintLevel, CHAR* Message, ...); ULONG __cdecl DbgPrint(CHAR* fmt, ...); } #if 0 #define DBGPRINT(x) ScsiDebugPrint x #define DBGLEVEL 0, #elif 1 #define DBGPRINT(x) DbgPrint x #define DBGLEVEL #else #define DBGPRINT(x) #endif #define SRB_FUNCTION_EXECUTE_SCSI 0x00 #define SRB_FUNCTION_CLAIM_DEVICE 0x01 #define SRB_FUNCTION_IO_CONTROL 0x02 #define SRB_FUNCTION_RECEIVE_EVENT 0x03 #define SRB_FUNCTION_RELEASE_QUEUE 0x04 #define SRB_FUNCTION_ATTACH_DEVICE 0x05 #define SRB_FUNCTION_RELEASE_DEVICE 0x06 #define SRB_FUNCTION_SHUTDOWN 0x07 #define SRB_FUNCTION_FLUSH 0x08 #define SRB_FUNCTION_ABORT_COMMAND 0x10 #define SRB_FUNCTION_RELEASE_RECOVERY 0x11 #define SRB_FUNCTION_RESET_BUS 0x12 #define SRB_FUNCTION_RESET_DEVICE 0x13 #define SRB_FUNCTION_TERMINATE_IO 0x14 #define SRB_FUNCTION_FLUSH_QUEUE 0x15 #define SRB_FUNCTION_REMOVE_DEVICE 0x16 #define SRB_FUNCTION_WMI 0x17 #define SRB_FUNCTION_LOCK_QUEUE 0x18 #define SRB_FUNCTION_UNLOCK_QUEUE 0x19 #define SRB_FLAGS_QUEUE_ACTION_ENABLE 0x00000002 #define SRB_FLAGS_DISABLE_DISCONNECT 0x00000004 #define SRB_FLAGS_DISABLE_SYNCH_TRANSFER 0x00000008 #define SRB_FLAGS_BYPASS_FROZEN_QUEUE 0x00000010 #define SRB_FLAGS_DISABLE_AUTOSENSE 0x00000020 #define SRB_FLAGS_DATA_IN 0x00000040 #define SRB_FLAGS_DATA_OUT 0x00000080 #define SRB_FLAGS_NO_DATA_TRANSFER 0x00000000 #define SRB_FLAGS_UNSPECIFIED_DIRECTION (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) #define SRB_FLAGS_NO_QUEUE_FREEZE 0x00000100 #define SRB_FLAGS_ADAPTER_CACHE_ENABLE 0x00000200 #define SRB_FLAGS_IS_ACTIVE 0x00010000 #define SRB_FLAGS_ALLOCATED_FROM_ZONE 0x00020000 #define SRB_FLAGS_SGLIST_FROM_POOL 0x00040000 #define SRB_FLAGS_BYPASS_LOCKED_QUEUE 0x00080000 #define SRB_FLAGS_NO_KEEP_AWAKE 0x00100000 #define SRB_FLAGS_PORT_DRIVER_RESERVED 0x0F000000 #define SRB_FLAGS_CLASS_DRIVER_RESERVED 0xF0000000