Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -0,0 +1,410 @@
#ifndef ASPI_INCLUDED
#define ASPI_INCLUDED
#include <Windows.h>
#include <Stdio.h>
#include <Stdlib.h>
// Handle to the ASPI libaray
extern HINSTANCE hAspiLib;
void GetAspiError(int nErrorCode,LPSTR lpszError);
// 1 byte alignment or SCSI structures
#pragma pack(push,1)
#define MAX_SCSIDEVICES 16
#define TIMEOUT 10000
typedef void (*POSTPROCFUNC)();
typedef struct TOC_TAG
{
BYTE _reserved1;
BYTE bFlags;
BYTE bTrack;
BYTE _reserved2;
DWORD dwStartSector;
} TOC;
// The SRB_Flags are defined below. These flags may be OR'd together to form
// the final value for SRB_Flags in the SRB. Note that SRB_POSTING and
// SRB_EVENT_NOTIFY are mutually exclusive, as are SRB_DIR_IN and SRB_DIR_OUT. In
// addition, the directioin bits (SRB_DIR_IN and SRB_DIR_OUT) MUST be set
// correctly on commands which transfer data. Using SRB_DIR_SCSI is no longer
// an option as in ASPI for DOS and ASPI for Win16.
#define SRB_POSTING 0x01 // Enable ASPI command completion posting. See section on posting below.
#define SRB_ENABLE_RESIDUAL_COUNT 0x04 // Enables reporting of residual byte count.This flag is only significant if the host adapter reports support for residual byte count in the SC_HA_INQUIRY command. When data underrun occurs, the SRB_BufLen field is updated to reflect the remaining bytes to transfer.
#define SRB_DIR_IN 0x08 // Data transfer from SCSI target to host.
#define SRB_DIR_OUT 0x10 // Data transfer from host to SCSI target.
#define SRB_EVENT_NOTIFY 0x40 // Enable ASPI command event notification. See section on event notification below.
// Inquiry DeviceTypeCodes
#define DTC_DISK 0x00 // Direct-access device
#define DTC_TAPE 0x01 // Sequential-access device
#define DTC_PRINTER 0x02 // Printer device
#define DTC_PROCESSOR 0x03 // Processor device
#define DTC_WORM 0x04 // Write-once device
#define DTC_CDROM 0x05 // CD-ROM device
#define DTC_SCANNER 0x06 // Scanner device
#define DTC_OPTICAL 0x07 // Optical memory device
#define DTC_JUKEBOX 0x08 // Medium changer device
#define DTC_COMM 0x09 // Communications device
#define DTC_PREPRESS1 0x0A // Pre-press device 1
#define DTC_PREPRESS2 0x0B // Pre-press device 2
#define DTC_UNKNOWN 0x1F // Unknown or no device type
/***************************************************************************
** SRB Status
***************************************************************************/
#define SS_PENDING 0x00 /* SRB being processed */
#define SS_COMP 0x01 /* SRB completed without error */
#define SS_ABORTED 0x02 /* SRB aborted */
#define SS_ABORT_FAIL 0x03 /* Unable to abort SRB */
#define SS_ERR 0x04 /* SRB completed with error */
#define SS_INVALID_CMD 0x80 /* Invalid ASPI command */
#define SS_INVALID_HA 0x81 /* Invalid host adapter number */
#define SS_NO_DEVICE 0x82 /* SCSI device not installed */
#define SS_INVALID_SRB 0xE0 /* Invalid parameter set in SRB */
#define SS_OLD_MANAGER 0xE1 /* ASPI manager doesn't support */
/* windows */
#define SS_BUFFER_ALIGN 0xE1 /* Buffer not aligned (replaces */
/* SS_OLD_MANAGER in Win32) */
#define SS_ILLEGAL_MODE 0xE2 /* Unsupported Windows mode */
#define SS_NO_ASPI 0xE3 /* No ASPI managers */
#define SS_FAILED_INIT 0xE4 /* ASPI for windows failed init */
#define SS_ASPI_IS_BUSY 0xE5 /* No resources available to */
/* execute command */
#define SS_BUFFER_TO_BIG 0xE6 /* Buffer size too big to handle */
#define SS_BUFFER_TOO_BIG 0xE6 /* Correct spelling of 'too' */
#define SS_MISMATCHED_COMPONENTS 0xE7 /* The DLLs/EXEs of ASPI don't */
/* version check */
#define SS_NO_ADAPTERS 0xE8 /* No host adapters to manager */
#define SS_INSUFFICIENT_RESOURCES 0xE9 /* Couldn't allocate resources */
/* needed to init */
#define SS_ASPI_IS_SHUTDOWN 0xEA /* Call came to ASPI after */
/* PROCESS_DETACH */
#define SS_BAD_INSTALL 0xEB /* The DLL or other components */
/* are installed wrong */
// SRB defines
#define SC_HA_INQUIRY 0x00 // Get information about installed host adapters,including the number of installed adapters.
#define SC_GET_DEV_TYPE 0x01 // Get information about installed SCSI devices.
#define SC_EXEC_SCSI_CMD 0x02 // Execute SCSI I/O.
#define SC_ABORT_SRB 0x03 // Abort an outstanding I/O request.
#define SC_RESET_DEV 0x04 // Reset an individual SCSI target.
#define SC_GET_DISK_INFO 0x06 // Get information on disk type SCSI devices (not available under Windows NT).
#define SC_GETSET_TIMEOUTS 0x08
// MISC defines
#define CDSAMPLEFREQ 44100
#define TRACKSPERSEC 75
#define CB_CDDASECTOR 2352
#define CB_QSUBCHANNEL 0
#define CB_CDROMSECTOR 2048
#define CB_AUDIO (CB_CDDASECTOR-CB_QSUBCHANNEL)
typedef struct
{
BYTE SRB_Cmd; // ASPI command code
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // ASPI request flags
DWORD SRB_Hdr_Rsvd; // Reserved, MUST = 0
} SRB_HEADER, *LPSRB;
typedef struct
{
BYTE SRB_Cmd; // ASPI command code = SC_HA_INQUIRY
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // ASPI request flags
DWORD SRB_Hdr_Rsvd; // Reserved, MUST = 0
BYTE HA_Count; // Number of host adapters present
BYTE HA_SCSI_ID; // SCSI ID of host adapter
BYTE HA_ManagerId[16]; // String describing the manager
BYTE HA_Identifier[16]; // String describing the host adapter
BYTE HA_Unique[16]; // Host Adapter Unique parameters
WORD HA_Rsvd1;
} SRB_HAINQUIRY, *LPSRB_HAINQUIRY;
typedef struct
{
BYTE SRB_Cmd; // ASPI command code = SC_GET_DEV_TYPE
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // Reserved
DWORD SRB_Hdr_Rsvd; // Reserved
BYTE SRB_Target; // Target's SCSI ID
BYTE SRB_Lun; // Target's LUN number
BYTE SRB_DeviceType; // Target's peripheral device type
BYTE SRB_Rsvd1; // Reserved for alignment
} SRB_GDEVBLOCK, *LPSRB_GDEVBLOCK;
#define SENSE_LEN 14 // Maximum sense length
typedef struct
{
BYTE SRB_Cmd; // ASPI command code = SC_EXEC_SCSI_CMD
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // ASPI request flags
DWORD SRB_Hdr_Rsvd; // Reserved
BYTE SRB_Target; // Target's SCSI ID
BYTE SRB_Lun; // Target's LUN number
WORD SRB_Rsvd1; // Reserved for Alignment
DWORD SRB_BufLen; // Data Allocation Length
BYTE *SRB_BufPointer; // Data Buffer Point
BYTE SRB_SenseLen; // Sense Allocation Length
BYTE SRB_CDBLen; // CDB Length
BYTE SRB_HaStat; // Host Adapter Status
BYTE SRB_TargStat; // Target Status
void (*SRB_PostProc)(); // Post routine
void *SRB_Rsvd2; // Reserved
BYTE SRB_Rsvd3[16]; // Reserved for expansion
BYTE CDBByte[16]; // SCSI CDB
BYTE SenseArea[SENSE_LEN+2]; // Request Sense buffer
} SRB_EXECSCSICMD, *LPSRB_EXECSCSICMD;
typedef struct
{
BYTE SRB_Cmd; // ASPI command code = SC_EXEC_SCSI_CMD
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // Reserved
DWORD SRB_Hdr_Rsvd; // Reserved
BYTE SRB_Target; // Target's SCSI ID
BYTE SRB_Lun; // Target's LUN number
BYTE SRB_DriveFlags; // Driver flags
BYTE SRB_Int13HDriveInfo;// Host Adapter Status
BYTE SRB_Heads; // Preferred number of heads translation
BYTE SRB_Sectors; // Preferred number of sectors translation
BYTE SRB_Rsvd1[10]; // Reserved
} SRB_GETDISKINFO, *LPSRB_GETDISKINFO;
typedef struct
{
BYTE SRB_Cmd; // ASPI command code = SC_RESET_DEV
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // Reserved
DWORD SRB_Hdr_Rsvd; // Reserved
BYTE SRB_Target; // Target's SCSI ID
BYTE SRB_Lun; // Target's LUN number
BYTE SRB_Rsvd1[12]; // Reserved for Alignment
BYTE SRB_HaStat; // Host Adapter Status
BYTE SRB_TargStat; // Target Status
void *SRB_PostProc; // Post routine
void *SRB_Rsvd2; // Reserved
BYTE SRB_Rsvd3[32]; // Reserved
} SRB_BUSDEVICERESET, *LPSRB_BUSDEVICERESET;
typedef struct
{
BYTE SRB_Cmd; /* 00/000 ASPI cmd code == SC_ABORT_SRB */
BYTE SRB_Status; /* 01/001 ASPI command status byte */
BYTE SRB_HaID; /* 02/002 ASPI host adapter number */
BYTE SRB_Flags; /* 03/003 Reserved, must = 0 */
DWORD SRB_Hdr_Rsvd; /* 04/004 Reserved, must = 0 */
void *SRB_ToAbort; /* 08/008 Pointer to SRB to abort */
} SRB_Abort, *PSRB_Abort, FAR *LPSRB_Abort;
typedef unsigned char Ucbit;
typedef unsigned char u_char;
#define MP_P_CODE \
Ucbit p_code : 6; \
Ucbit p_res : 1; \
Ucbit parsave : 1
// CD Cap / mech status
typedef struct SCSICDMODEPAGE2A_TAG
{
MP_P_CODE; // parsave & pagecode (0)
u_char p_len; // 0x14 = 20 Bytes (1)
Ucbit cd_r_read : 1; // Reads CD-R media (2)
Ucbit cd_rw_read : 1; // Reads CD-RW media
Ucbit method2 : 1; // Reads fixed packet method2 media
Ucbit dvd_rom_read: 1; // Reads DVD ROM media
Ucbit dvd_r_read : 1; // Reads DVD-R media
Ucbit dvd_ram_read: 1; // Reads DVD-RAM media
Ucbit res_2_67 : 2; // Reserved
Ucbit cd_r_write : 1; // Supports writing CD-R media (3)
Ucbit cd_rw_write : 1; // Supports writing CD-RW media
Ucbit test_write : 1; // Supports emulation write
Ucbit res_3_3 : 1; // Reserved
Ucbit dvd_r_write : 1; // Supports writing DVD-R media
Ucbit dvd_ram_write: 1; // Supports writing DVD-RAM media
Ucbit res_3_67 : 2; // Reserved
Ucbit audio_play : 1; // Supports Audio play operation (4)
Ucbit composite : 1; // Deliveres composite A/V stream
Ucbit digital_port_2: 1; // Supports digital output on port 2
Ucbit digital_port_1: 1; // Supports digital output on port 1
Ucbit mode_2_form_1: 1; // Reads Mode-2 form 1 media (XA)
Ucbit mode_2_form_2: 1; // Reads Mode-2 form 2 media
Ucbit multi_session: 1; // Reads multi-session media
Ucbit res_4 : 1; // Reserved
Ucbit cd_da_supported: 1; // Reads audio data with READ CD cmd
Ucbit cd_da_accurate: 1; // READ CD data stream is accurate
Ucbit rw_supported: 1; // Reads R-W sub channel information
Ucbit rw_deint_cor: 1; // Reads de-interleved R-W sub chan
Ucbit c2_pointers : 1; // Supports C2 error pointers
Ucbit ISRC : 1; // Reads ISRC information
Ucbit UPC : 1; // Reads media catalog number (UPC)
Ucbit read_bar_code: 1; // Supports reading bar codes
Ucbit lock : 1; // PREVENT/ALLOW may lock media (5)
Ucbit lock_state : 1; // Lock state 0=unlocked 1=locked
Ucbit prevent_jumper: 1; // State of prev/allow jumper 0=pres
Ucbit eject : 1; // Ejects disc/cartr with STOP LoEj
Ucbit res_6_4 : 1; // Reserved
Ucbit loading_type: 3; // Loading mechanism type
Ucbit sep_chan_vol: 1; // Vol controls each channel separat (6)
Ucbit sep_chan_mute: 1; // Mute controls each channel separat
Ucbit disk_present_rep:1; // Changer supports disk present rep
Ucbit sw_slot_sel:1; // Load empty slot in changer
Ucbit res_7 : 4; // Reserved
BYTE ReadSpeedH; // Max. read speed in KB/s (7)
BYTE ReadSpeedL; // Max. read speed in KB/s (7)
u_char num_vol_levels[2]; // # of supported volume levels (9)
u_char buffer_size[2]; // Buffer size for the data in KB (11)
u_char cur_read_speed[2]; // Current read speed in KB/s (13)
u_char res_16; // Reserved (14)
Ucbit res_17_0: 1; // Reserved (15)
Ucbit BCK : 1; // Data valid on falling edge of BCK
Ucbit RCK : 1; // Set: HIGH high LRCK=left channel
Ucbit LSBF : 1; // Set: LSB first Clear: MSB first
Ucbit length : 2; // 0=32BCKs 1=16BCKs 2=24BCKs 3=24I2c
Ucbit res_17 : 2; // Reserved
u_char max_write_speed[2]; // Max. write speed supported in KB/s (17)
u_char cur_write_speed[2]; // Current write speed in KB/s (19)
} SCSICDMODEPAGE2A;
char *fillbytes(void *tov, int cnt, char val);
typedef struct SCISMODEHEADER_TAG {
Ucbit sense_data_len : 8;
u_char medium_type;
Ucbit res2 : 4;
Ucbit cache : 1;
Ucbit res : 2;
Ucbit write_prot : 1;
BYTE nBlockLen;
} SCISMODEHEADER;
typedef struct SCSIMODEHDR_6_TAG {
BYTE btModeDataLen; // 0
BYTE btMediumType; // 1
BYTE btDevSpecificParam; // 2
BYTE btBlkDescrLen; // 3
} SCSIMODEHDR_6;
typedef struct SCSIMODEHDR_10_TAG {
BYTE btModeDataLenH; // 0
BYTE btModeDataLenL; // 1
BYTE btMediumType; // 2
BYTE btDevSpecificParam; // 3
BYTE btReserved1; // 4
BYTE btReserved2; // 5
BYTE btBlkDescrLenH; // 6
BYTE btBlkDescrLenL; // 7
} SCSIMODEHDR_10;
typedef struct SCSIBLOCKDESCRIPTOR_TAG {
BYTE btDensity; // 0
BYTE btNumberOfBlocksH; // 1
BYTE btNumberOfBlocksM; // 2
BYTE btNumberOfBlocksL; // 3
BYTE btReserved; // 4
BYTE btBlockLenH; // 5
BYTE btBlockLenM; // 6
BYTE btBlockLenL; // 7
} SCSIBLOCKDESCRIPTOR;
// Error recovery Parameters
typedef struct SCSICDMODEPAGE1A_TAG{
MP_P_CODE; // 0 parsave & pagecode
u_char p_len; // 1 0x0A = 12 Bytes
Ucbit disa_correction : 1; // 2 Byte 2
Ucbit term_on_rec_err : 1;
Ucbit report_rec_err : 1;
Ucbit en_early_corr : 1;
Ucbit read_continuous : 1;
Ucbit tranfer_block : 1;
Ucbit en_auto_reall_r : 1;
Ucbit en_auto_reall_w : 1;
u_char rd_retry_count; // 3 Byte 3
u_char correction_span; // 4
char head_offset_count; // 5
char data_strobe_offset; // 6
u_char res; // 7
u_char wr_retry_count; // 8
u_char res_tape[2]; // 9
u_char recov_timelim[2]; // 11
} SCSICDMODEPAGE1A;
typedef struct
{
BYTE SRB_Cmd; // ASPI command code = SC_GETSET_TIMEOUTS
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // ASPI request flags
DWORD SRB_Hdr_Rsvd; // Reserved
BYTE SRB_Target; // Target's SCSI ID
BYTE SRB_Lun; // Target's LUN number
DWORD SRB_Timeout; // Timeout in half seconds
}
SRB_GetSetTimeouts, *PSRB_GetSetTimeouts;
typedef struct
{
LPBYTE AB_BufPointer; // Pointer to the ASPI allocated buffer
DWORD AB_BufLen; // Length in bytes of the buffer
DWORD AB_ZeroFill; // Flag set to 1 if buffer should be zeroed
DWORD AB_Reserved; // Reserved, MUST = 0
}
ASPI32BUFF, *PASPI32BUFF;
#pragma pack(pop)
#endif

View file

@ -0,0 +1,378 @@
// ----------------------------------------------
// - ASPIFUNC implementation file -
// - Written 1996-1998 by Christoph Schmelnik -
// ----------------------------------------------
// Version 1.40 : 24.02.1998
// Changes:
// Set correct direction flags, to work with NT device IO interface and ATAPI drives
// Added Immediate paremeter for WaitSCSIRequest to allow detection of buffer underruns
#include <stddef.h>
#include "aspifunc.h"
HMODULE hDLL=0;
VOIDPROC GetASPI32SupportInfo;
SRBPROC SendASPI32Command;
int ASPIInstalled;
int RunningNT;
int NumberOfHostAdapters;
//Implementation of base ASPI Functions
BOOL HAInquiry(int HostAdapterNumber,char *ManagerID, char *HAID,THAUnique &HAUnique)
{
SRB_HAInquiry MySRB;
DWORD ASPI_Status;
memset(&MySRB,0,sizeof(SRB_HAInquiry));
MySRB.SRB_Cmd = SC_HA_INQUIRY;
MySRB.SRB_HaId = HostAdapterNumber;
MySRB.SRB_Flags = 0;
MySRB.SRB_Hdr_Rsvd = 0;
ASPI_Status = SendASPI32Command ( (LPSRB) &MySRB );
if (ASPI_Status!=SS_COMP)
return FALSE;
HAUnique=MySRB.HA_Unique;
for (int i=0; i<16; i++)
{
ManagerID[i]=MySRB.HA_ManagerId[i];
HAID[i]=MySRB.HA_Identifier[i];
}
ManagerID[16]=0;
HAID[16]=0;
return TRUE;
}
int GetDeviceType(int HostAdapterNumber,int TargetId,int LUN)
{
SRB_GDEVBlock MySRB;
DWORD ASPI_Status;
memset(&MySRB,0,sizeof(SRB_GDEVBlock));
MySRB.SRB_Cmd = SC_GET_DEV_TYPE;
MySRB.SRB_HaId = HostAdapterNumber;
MySRB.SRB_Flags = 0;
MySRB.SRB_Hdr_Rsvd = 0;
MySRB.SRB_Target = TargetId;
MySRB.SRB_Lun = LUN;
ASPI_Status = SendASPI32Command ((LPSRB)&MySRB);
/***************************************************/
/* If ASPI_Status == SS_COMP, MySRB.SRB_DeviceType */
/* will contain the peripheral device type. */
/***************************************************/
if (ASPI_Status==SS_COMP)
return MySRB.SRB_DeviceType;
return DTYPE_UNKNOWN;
}
BOOL ExecuteSCSIRequest(int HostAdapterNumber,int TargetId,int LUN,int RequestFlags,
TOpcode OpC, BYTE OpCLen,void *DataPtr, int DataLen, HANDLE hDriveEvent)
{
if ((HostAdapterNumber>=NumberOfHostAdapters) &&
RunningNT)
{
DWORD il, ol;
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sb;
ZeroMemory(&sb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
sb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
sb.sptd.CdbLength = OpCLen;
sb.sptd.DataIn = ((SRB_DIR_IN & RequestFlags) ? 1/*SCSI_IOCTL_DATA_IN*/ : 0/*SCSI_IOCTL_DATA_OUT*/);
sb.sptd.SenseInfoLength = 32;
sb.sptd.DataTransferLength = DataLen;
sb.sptd.TimeOutValue = 2;
sb.sptd.DataBuffer = (unsigned char*) DataPtr;
sb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
for (int i=0; i<OpCLen; i++) sb.sptd.Cdb[i]=OpC[i];
il = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);
if (DeviceIoControl(hDriveEvent, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sb, il, &sb, il, &ol, FALSE))
{
if (sb.sptd.ScsiStatus==0)
return TRUE;
}
return FALSE;
}
SRB_ExecSCSICmd MySRB;
DWORD ASPI_Status;
DWORD ASPIEventStatus;
memset(&MySRB,0,sizeof(SRB_ExecSCSICmd));
MySRB.SRB_Cmd = SC_EXEC_SCSI_CMD;
MySRB.SRB_HaId = HostAdapterNumber;
MySRB.SRB_Flags = RequestFlags|SRB_EVENT_NOTIFY;
MySRB.SRB_Hdr_Rsvd = 0;
MySRB.SRB_Target = TargetId;
MySRB.SRB_Lun = LUN;
MySRB.SRB_BufPointer = (unsigned char*) DataPtr;
MySRB.SRB_BufLen = DataLen;
MySRB.SRB_CDBLen = OpCLen;
MySRB.SRB_SenseLen = SENSE_LEN;
MySRB.SRB_PostProc = (void(__cdecl *)(void))hDriveEvent;
for (int i=0; i<OpCLen; i++) MySRB.CDBByte[i]=OpC[i];
ResetEvent(hDriveEvent);
ASPI_Status = SendASPI32Command ((LPSRB)&MySRB);
/**************************************************/
/* Block on event till signaled */
/**************************************************/
if ( MySRB.SRB_Status == SS_PENDING )
{
ASPIEventStatus = WaitForSingleObject(hDriveEvent, TIMEOUT);
/**************************************************/
/* Reset event to non-signaled state. */
/**************************************************/
if (ASPIEventStatus == WAIT_OBJECT_0)
ResetEvent(hDriveEvent);
else
{
OutputDebugString(L"Execute Timed out\n");
AbortSCSIRequest(MySRB);
}
}
if (MySRB.SRB_Status==SS_COMP)
return TRUE;
return FALSE;
}
void FillSCSIRequest(int HostAdapterNumber,int TargetId,int LUN,int RequestFlags,
TOpcode OpC, BYTE OpCLen,void *DataPtr, int DataLen,SRB_ExecSCSICmd &MySRB, HANDLE hDriveEvent)
{
memset(&MySRB,0,sizeof(SRB_ExecSCSICmd));
MySRB.SRB_Cmd = SC_EXEC_SCSI_CMD;
MySRB.SRB_HaId = HostAdapterNumber;
if ((HostAdapterNumber>=NumberOfHostAdapters) &&
RunningNT)
{
MySRB.SRB_Flags = RequestFlags;
}
else
{
MySRB.SRB_Flags = RequestFlags|SRB_EVENT_NOTIFY;
MySRB.SRB_Hdr_Rsvd = 0;
MySRB.SRB_PostProc = (void(__cdecl *)(void))hDriveEvent;
}
MySRB.SRB_Target = TargetId;
MySRB.SRB_Lun = LUN;
MySRB.SRB_BufPointer = (unsigned char*) DataPtr;
MySRB.SRB_BufLen = DataLen;
MySRB.SRB_CDBLen = OpCLen;
MySRB.SRB_SenseLen = SENSE_LEN;
for (int i=0; i<OpCLen; i++) MySRB.CDBByte[i]=OpC[i];
}
void ExecuteSCSIRequest(SRB_ExecSCSICmd &MySRB,HANDLE hDriveEvent)
{
if ((MySRB.SRB_HaId>=NumberOfHostAdapters) &&
RunningNT)
{
DWORD il, ol;
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sb;
ZeroMemory(&sb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
sb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
sb.sptd.PathId = 0;
sb.sptd.TargetId = 1;
sb.sptd.Lun = 0;
sb.sptd.CdbLength = MySRB.SRB_CDBLen;
sb.sptd.DataIn = MySRB.SRB_Flags;
sb.sptd.SenseInfoLength = 32;
sb.sptd.DataTransferLength = MySRB.SRB_BufLen;
sb.sptd.TimeOutValue = TIMEOUT;
sb.sptd.DataBuffer = MySRB.SRB_BufPointer;
sb.sptd.SenseInfoOffset =
offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
for (int i=0; i<MySRB.SRB_CDBLen; i++) sb.sptd.Cdb[i]=MySRB.CDBByte[i];
il = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);
if (DeviceIoControl(hDriveEvent, IOCTL_SCSI_PASS_THROUGH_DIRECT,
&sb, il, &sb, il, &ol, NULL))
if (sb.sptd.ScsiStatus==0)
{
MySRB.SRB_Status=SS_COMP;
return;
}
MySRB.SRB_Status=SS_ERR;
return;
}
DWORD ASPI_Status;
ResetEvent(hDriveEvent);
ASPI_Status = SendASPI32Command ((LPSRB)&MySRB);
}
BYTE WaitSCSIRequest(SRB_ExecSCSICmd &MySRB,HANDLE hDriveEvent,BOOL bImmediate)
{
if ((MySRB.SRB_HaId>=NumberOfHostAdapters) &&
RunningNT)
return MySRB.SRB_Status;
if ((MySRB.SRB_Status == SS_PENDING) &&
!bImmediate)
{
DWORD ASPIEventStatus = WaitForSingleObject(hDriveEvent, 100);
if (ASPIEventStatus == WAIT_OBJECT_0)
{
ResetEvent(hDriveEvent);
}
}
return MySRB.SRB_Status;
}
BOOL AbortSCSIRequest(SRB_ExecSCSICmd &StuckSRB)
{
SRB_Abort AbortSRB;
DWORD ASPIStatus;
AbortSRB.SRB_Cmd = SC_ABORT_SRB;
AbortSRB.SRB_HaId = StuckSRB.SRB_HaId;
AbortSRB.SRB_Flags = 0;
AbortSRB.SRB_Hdr_Rsvd = 0;
AbortSRB.SRB_ToAbort = (LPSRB)&StuckSRB;
ASPIStatus = SendASPI32Command ( (LPSRB)&AbortSRB );
return (ASPIStatus==SS_COMP);
}
int GetDeviceInfo(int HostAdapterNumber,int TargetId,int LUN,BYTE &SCSIType,char *VendorID,
char *ProductID,char *ProductRevision,HANDLE hDriveEvent)
{
struct InquireFormat
{
BYTE ConfigPara[8];
char VendorID[8];
char ProductID[16];
char ProductRevision[4];
} DeviceInfo;
TOpcode OpC;
OpC[0]=0x12;
OpC[1]=0;
OpC[2]=0;
OpC[3]=0;
OpC[4]=sizeof(DeviceInfo);
OpC[5]=0;
memset(&DeviceInfo,0,sizeof(DeviceInfo));
BOOL r=ExecuteSCSIRequest(HostAdapterNumber,TargetId,LUN,SRB_DIR_IN,OpC,6,(void*)&DeviceInfo,sizeof(DeviceInfo),hDriveEvent);
if (r)
{
for (int i=0; i<16; i++)
{
if (i<8) VendorID[i]=DeviceInfo.VendorID[i];
ProductID[i]=DeviceInfo.ProductID[i];
if (i<4) ProductRevision[i]=DeviceInfo.ProductRevision[i];
}
VendorID[8]=0;
ProductID[16]=0;
ProductRevision[4]=0;
SCSIType=DeviceInfo.ConfigPara[2] & 0x0f;
return DeviceInfo.ConfigPara[0];
}
return DTYPE_UNKNOWN;
}
BOOL TestUnitReady(int HostAdapterNumber,int TargetId,int LUN,HANDLE hDriveEvent)
{
TOpcode OpC;
OpC[0]=0;
OpC[1]=0;
OpC[2]=0;
OpC[3]=0;
OpC[4]=0;
OpC[5]=0;
return ExecuteSCSIRequest(HostAdapterNumber,TargetId,LUN,SRB_DIR_IN,OpC,6,NULL,0,hDriveEvent);
}
BOOL ModeSense(int HostAdapterNumber,int TargetId,int LUN,TDriveMode &ModeData,int Size,int PageCode,HANDLE hDriveEvent)
{
// while (!TestUnitReady(HostAdapterNumber,TargetId,LUN));
TOpcode OpC;
OpC[0]=0x1a;
OpC[1]=0x00;
OpC[2]=PageCode;
OpC[3]=0x00;
OpC[4]=Size;
OpC[5]=0x00;
return ExecuteSCSIRequest(HostAdapterNumber,TargetId,LUN,SRB_DIR_IN,OpC,6,(void *)&ModeData,Size,hDriveEvent);
}
BOOL ATAPIModeSense(int HostAdapterNumber,int TargetId,int LUN,TDriveMode &ModeData,int Size,int PageCode,HANDLE hDriveEvent)
{
// while (!TestUnitReady(HostAdapterNumber,TargetId,LUN));
TOpcode OpC;
OpC[0]=0x5a;
OpC[1]=0x00;
OpC[2]=PageCode;
OpC[3]=0x00;
OpC[4]=0x00;
OpC[5]=0x00;
OpC[6]=0x00;
OpC[7]=0x00;
OpC[8]=Size;
OpC[9]=0x00;
OpC[10]=0x00;
OpC[11]=0x00;
return ExecuteSCSIRequest(HostAdapterNumber,TargetId,LUN,SRB_DIR_IN,OpC,12,(void *)&ModeData,Size,hDriveEvent);
}
BOOL addModeSense(int HostAdapterNumber,int TargetId,int LUN,TDriveMode &ModeData,int Size,HANDLE hDriveEvent)
{
// while (!TestUnitReady(HostAdapterNumber,TargetId,LUN));
TOpcode OpC;
OpC[0]=0xca;
OpC[1]=0x08;
OpC[2]=0x0f;
OpC[3]=0x00;
OpC[4]=0x00;
OpC[5]=0x00;
OpC[6]=0x00;
OpC[7]=0x00;
OpC[8]=Size;
OpC[9]=0x00;
return ExecuteSCSIRequest(HostAdapterNumber,TargetId,LUN,SRB_DIR_IN,OpC,10,(void *)&ModeData,Size,hDriveEvent);
}
BOOL ModeSelect(int HostAdapterNumber,int TargetId,int LUN,TDriveMode &ModeData,int Size,HANDLE hDriveEvent)
{
// while (!TestUnitReady(HostAdapterNumber,TargetId,LUN));
TOpcode OpC;
OpC[0]=0x15;
if (Size==12)
OpC[1]=0x00;
else
OpC[1]=0x10;
OpC[2]=0x00;
OpC[3]=0x00;
OpC[4]=Size;
OpC[5]=0x00;
return ExecuteSCSIRequest(HostAdapterNumber,TargetId,LUN,SRB_DIR_OUT,OpC,6,(void *)&ModeData,Size,hDriveEvent);
}
BOOL addModeSelect(int HostAdapterNumber,int TargetId,int LUN,TDriveMode &ModeData,int Size,HANDLE hDriveEvent)
{
// while (!TestUnitReady(HostAdapterNumber,TargetId,LUN));
TOpcode OpC;
OpC[0]=0xc5;
OpC[1]=0x10;
OpC[2]=0x00;
OpC[3]=0x00;
OpC[4]=0x00;
OpC[5]=0x00;
OpC[6]=0x00;
OpC[7]=0x00;
OpC[8]=Size;
OpC[9]=0x00;
return ExecuteSCSIRequest(HostAdapterNumber,TargetId,LUN,SRB_DIR_OUT,OpC,10,(void *)&ModeData,Size,hDriveEvent);
}
BOOL SCSIMaxBlocks(HANDLE fh, int *mb)
{
DWORD ol;
IO_SCSI_CAPABILITIES ca;
if (DeviceIoControl(fh,IOCTL_SCSI_GET_CAPABILITIES,NULL,0,
&ca,sizeof(IO_SCSI_CAPABILITIES),&ol,NULL))
{
*mb=(int)ca.MaximumTransferLength;
return TRUE;
}
return FALSE;
}

View file

@ -0,0 +1,101 @@
// ----------------------------------------------
// - ASPIFUNC header file -
// - Written 1996-1998 by Christoph Schmelnik -
// ----------------------------------------------
// Version 1.40 : 24.02.1998
// Changes:
// function prototype for WaitSCSIRequest extended by immediate parameter
#ifndef _ASPIFUNC_H
#define _ASPIFUNC_H
#ifndef STRICT
#define STRICT // Enable strict tape checking
#define WIN32_LEAN_AND_MEAN // Include only needed header files
#endif
#include <windows.h>
#include <stdio.h>
#include <winioctl.h>
#include "winaspi.h"
#include "scsidefs.h"
/*#ifdef DLL
#define DACDLL __declspec(dllexport)
#else
#define DACDLL __declspec(dllimport)
#endif*/
#define DACDLL
typedef DWORD (__cdecl *VOIDPROC)();
typedef DWORD (__cdecl *SRBPROC)(LPSRB);
typedef BYTE TOpcode[30];
// NT DeviceIO Structures
#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER
#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
typedef struct _IO_SCSI_CAPABILITIES {
ULONG Length;
ULONG MaximumTransferLength;
ULONG MaximumPhysicalPages;
ULONG SupportedAsynchronousEvents;
ULONG AlignmentMask;
BOOLEAN TaggedQueuing;
BOOLEAN AdapterScansDown;
BOOLEAN AdapterUsesPio;
} IO_SCSI_CAPABILITIES, *PIO_SCSI_CAPABILITIES;
typedef struct _SCSI_PASS_THROUGH_DIRECT {
USHORT Length;
UCHAR ScsiStatus;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
UCHAR CdbLength;
UCHAR SenseInfoLength;
UCHAR DataIn;
ULONG DataTransferLength;
ULONG TimeOutValue;
PVOID DataBuffer;
ULONG SenseInfoOffset;
UCHAR Cdb[16];
} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
typedef struct _SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER {
SCSI_PASS_THROUGH_DIRECT sptd;
ULONG Filler; // realign buffer to double word boundary
UCHAR ucSenseBuf[32];
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
extern HMODULE hDLL;
extern VOIDPROC GetASPI32SupportInfo;
extern SRBPROC SendASPI32Command;
extern int ASPIInstalled;
extern int RunningNT;
extern int NumberOfHostAdapters;
// base ASPI functions
int DACDLL GetDeviceType(int HostAdapterNumber,int TargetId,int LUN);
BOOL ExecuteSCSIRequest(int HostAdapterNumber,int TargetId,int LUN,int RequestFlags,
TOpcode OpC, BYTE OpCLen,void *DataPtr, int DataLen,HANDLE hDriveEvent);
void ExecuteSCSIRequest(SRB_ExecSCSICmd &MySRB,HANDLE hDriveEvent);
void FillSCSIRequest(int HostAdapterNumber,int TargetId,int LUN,int RequestFlags,
TOpcode OpC, BYTE OpCLen,void *DataPtr, int DataLen,SRB_ExecSCSICmd &MySRB,HANDLE hDriveEvent);
BYTE WaitSCSIRequest(SRB_ExecSCSICmd &MySRB,HANDLE hDriveEvent,BOOL bImmediate=FALSE);
BOOL AbortSCSIRequest(SRB_ExecSCSICmd &StuckSRB);
int GetDeviceInfo(int HostAdapterNumber,int TargetId,int LUN,BYTE &SCSIType,char *VendorID,
char *ProductID,char *ProductRevision,HANDLE hDriveEvent);
BOOL HAInquiry(int HostAdapterNumber,char *ManagerID, char *HAID,THAUnique &HAUnique);
BOOL TestUnitReady(int HostAdapterNumber,int TargetId,int LUN,HANDLE hDriveEvent);
BOOL ModeSense(int HostAdapterNumber,int TargetId,int LUN,TDriveMode &ModeData,int Size,int PageCode,HANDLE hDriveEvent);
BOOL ATAPIModeSense(int HostAdapterNumber,int TargetId,int LUN,TDriveMode &ModeData,int Size,int PageCode,HANDLE hDriveEvent);
BOOL addModeSense(int HostAdapterNumber,int TargetId,int LUN,TDriveMode &ModeData,int Size,HANDLE hDriveEvent);
BOOL ModeSelect(int HostAdapterNumber,int TargetId,int LUN,TDriveMode &ModeData,int Size,HANDLE hDriveEvent);
BOOL addModeSelect(int HostAdapterNumber,int TargetId,int LUN,TDriveMode &ModeData,int Size,HANDLE hDriveEvent);
BOOL SCSIMaxBlocks(HANDLE fh, int *mb);
#endif //_ASPIFUNC_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,127 @@
# Microsoft Developer Studio Project File - Name="Dac32" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** NICHT BEARBEITEN **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=Dac32 - Win32 Release
!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
!MESSAGE
!MESSAGE NMAKE /f "Dac32.mak".
!MESSAGE
!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
!MESSAGE
!MESSAGE NMAKE /f "Dac32.mak" CFG="Dac32 - Win32 Release"
!MESSAGE
!MESSAGE Für die Konfiguration stehen zur Auswahl:
!MESSAGE
!MESSAGE "Dac32 - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Dac32 - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Win32/Digital Audio Copy/DAC32 DLL", FAAAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "Dac32 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\WinRel"
# PROP BASE Intermediate_Dir ".\WinRel"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /YX /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "DLL" /Fr /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# SUBTRACT LINK32 /map /nodefaultlib
!ELSEIF "$(CFG)" == "Dac32 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\WinDebug"
# PROP BASE Intermediate_Dir ".\WinDebug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Debug"
# PROP Intermediate_Dir ".\Debug"
# ADD BASE CPP /nologo /MT /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "DLL" /Fr /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# SUBTRACT LINK32 /nodefaultlib
!ENDIF
# Begin Target
# Name "Dac32 - Win32 Release"
# Name "Dac32 - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=.\aspifunc.cpp
# End Source File
# Begin Source File
SOURCE=.\dac32.cpp
# End Source File
# Begin Source File
SOURCE=.\dac32.rc
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\Aspifunc.h
# End Source File
# Begin Source File
SOURCE=.\Dac32.h
# End Source File
# Begin Source File
SOURCE=.\Scsidefs.h
# End Source File
# Begin Source File
SOURCE=.\Winaspi.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View file

@ -0,0 +1,775 @@
// ----------------------------------------------
// - DAC32.DLL Header Datei -
// - Written 1996-1998 by Christoph Schmelnik -
// ----------------------------------------------
// Changes
// ===========
// Version 1.2 :
// -CMapDrive supports now up to 34 Host Adapters, because now it could access the drives under
// NT with the DeviceControl Interface
// The required information for this is coded as:
// Drives accessed over the new Interface have a HostAdapterNumber above or equal to the
// NumberOfHostAdapters (global Information).
// The ID consists of the good old drive number, like in DOS.
// The LUN is not used for the configuration, but it is used to hold the open handle to the device
// The Burstmodus couldn't be used with the new access mode, so the default setting for those
// drives is the Normal-mode. (For those drives is no difference between Burst- and Normal-mode)
// -LoadASPI checks now the Windows Version and hold this result global in the DLL
// -The Constructor of CSCSCD opens the handles to the new devices
// -The destructor closes those handles
// Interface changes are not required but some values must be handled differnt to avoid
// misconfiguring, e.g. it is not allowed to configure the new drives ID, LUN, and HostAdapterNumber
// -A bug in CWaveSave regarding conversion to mixed mono has been fixed.
//
// Version 1.33 : 18.01.1998
// Changes:
// Added speed selection support for all current Plextor drives
//
// Version 1.40 : 24.02.1998
// Changes:
// Set correct direction flags, to work with NT device IO interface and ATAPI drives
// Changed main CD detection to TestUnitReady
// Removed CD detection from Audio Status Info
// Added hopefully correct read command for Matsushita/Panasonic drives
// Added Parameters to CDAC class to allow the disabling of the audio test and to spin up the drive for a specified time
// in seconds to avoid spin up problems on some drives. Both parameters have default values so it behaves like the old version
// without the additional parameters
// Added Parameter to the constructor of CWaveSave to disable writing any Headers. Also this parameter has a default to work like
// before.
// Added virtual function in CDAC to report buffer underruns in Burst Copy Mode
// For the last feature an immediate parameter in WaitCDDA is added
// GetLastSense function added to return the sense information for the last read audio command
// Configuration in CMapDrive extended by new features
// Fixed GetRedBook operator in CCDAdress
// Added function to CD Class to read Media Cataloge Number
//
// Version 1.41 : 28.04.1998
// Changes:
// New GetInfoEx() function in CMapDrive, to allow a better result checking.
//
// Version 1.42 : 02.08.1998
// Changes:
// Added GetLastReadableAddress function to get the last readable Sektor of a session.
// Added a flag in the drive properties for the function.
// Added this function to the CDAC object.
//
// Version 1.43 : 23.12.1998
// Changes:
// Added Wave and DAC classes are now available in a MT version, the old versions will not longer be updated.
//
// Version 1.44 : 10.03.1999
// Changes:
// Added Support for current Plextor CDROM drives and CD-Writers.
// Added Support for Jukeboxes
// Changed Handling of the Ringbuffer
//
// Version 1.45 : 15.08.1999
// Changes:
// Added Enhanced error detection for Plextor drives.
// Several Bugfixes (initialising under NT and Ringbuffer specific)
//
// Version 1.45-Build 11 : 11.11.1999
// Changes:
// Added a check for the MaxSektor parameter in CBaseWaveMT to avoid Program failures even if the applications provides an invalid value.
// Changed source to comile with Borland compiler
// Added MMC-2 Type which will be default for Sony CD-Writers 140 and 928
// Skip Virtual CD devices in Bus scan
// Fixed Array out of bound bug in drive detection.
#ifndef _DAC32_H
#define _DAC32_H
#ifndef STRICT
#define STRICT // Use strct typechecking
#define WIN32_LEAN_AND_MEAN // compile only important Headerfiles
#endif
#include <windows.h>
#include <stdio.h>
#include "aspifunc.h"
/*#ifdef DLL
#define DACDLL __declspec(dllexport)
#else
#define DACDLL __declspec(dllimport)
#endif*/
#define DACDLL
#ifdef _DEBUG
#define DBGOUT(sz) OutputDebugString(sz)
#else
#define DBGOUT(sz)
#endif
//The Errormessages for the CD and DAC Classes
#define CDOK 0x000
#define CDUnknownDrive 0x001
#define CDDriveNotReady 0x002
#define CDUnknownCommand 0x003
#define CDSeekError 0x006
#define CDSectorNotFound 0x008
#define CDReadError 0x00B
#define CDGeneralError 0x00C
#define CDNoCD 0x00E
#define CDIllegalCDChange 0x00F
#define CDDriveNotFound 0x100
#define CDNoMemory 0x101
#define CDDACUnable 0x102
#define CDASPIError 0x103
#define CDUserBreak 0x104
#define CDTimeOut 0x105
//The Errormessage for the wave classes
#define WAVEFileOpenError 0x200
#define WAVEFileWriteError 0x201
#define WAVEChannelError 0x202
#define WAVEBitsError 0x203
#define WAVEFreqError 0x204
#define WAVENameError 0x205
#define WAVEMemoryError 0x206
//The supported base drive types
#define CDTYPE_TOSHIBA 0
#define CDTYPE_SONY 1
#define CDTYPE_NEC 2
#define CDTYPE_PHILIPS 3
#define CDTYPE_ATAPI 4
#define CDTYPE_TOSHNEW 5
#define CDTYPE_RICOH 6
#define CDTYPE_MATSHITA 7
#define CDTYPE_PLEXTOR 8
#define CDTYPE_CYBERDRV 9
#define JUKETYPE_SONY 0
#define JUKETYPE_PIONEER 1
//Amount of predefined drive mappings (relationship between real drives and base drive types)
#define MaxMappings 22 // pgo
//Amount of predefined jukebox mappings (relationship between real jukeboxes and base jukebox types)
#define MaxMappingsJuke 2
//The possible Copy modes
#define ModeNormal 0
#define ModeSynch 1
#define ModeBurst 2
//The possible Values for the DA Test
#define DATEST_ALLWAYS 0
#define DATEST_FIRSTTRACK 1
#define DATEST_NEVER 2
//The possible SpinUp modes
#define SPINUP_ALLWAYS 0
#define SPINUP_FIRSTTRACK 1
#define SPINUP_NEVER 2
// Amount of DWORD for the synchronisation
#define SynLen 512
// The Class for the Addressformats
class DACDLL CCDAdress
{
public:
void SetRedbook(long Value);
void SetHSG(long Value)
{
Adresse=Value;
};
long GetHSG()
{
return Adresse;
};
long GetRedbook()
{
long t;
t=(Adresse % 75)<<24;
t+=((Adresse / 75) % 60)<<16;
t+=((Adresse / 75) / 60)<<8;
return t;
};
CCDAdress &operator = (const CCDAdress &other)
{
Adresse=other.Adresse;
return (*this);
};
CCDAdress &operator + (const long Value)
{
Adresse+=Value;
return (*this);
};
CCDAdress &operator - (const long Value)
{
Adresse-=Value;
return (*this);
};
CCDAdress &operator += (const long Value)
{
Adresse+=Value;
return (*this);
};
CCDAdress &operator -= (const long Value)
{
Adresse-=Value;
return (*this);
};
private:
long Adresse;
};
// Typendeclarations
struct TDriveStatus
{
int DoorOpen; //Door open/closed
int DoorLocked; //Door locked/unlocked
int Cooked_RAW; //supports Cooked and RAW or Cooked
int Read_Write; //supports read and write
int Data_Audio_Video; //supports Data/Audio/Video or only Data
int Interleave; //supports Interleave regarding ISO
int CommandPrefetch; //supports Command Prefetching
int AudioChannelManipulation; //supports Audio-Channel Manipulation
int HSG_Redbook; //supports HSG and Redbook Addressing or only HSG
int CDPresent; //CD inserted or not
int RWSupport; //supports R-W-Sub Channels
};
struct TAudioStatus
{
BOOL Pause; //Play is paused
BOOL IsPlaying; //CD is playing
BOOL IsDone; //Play is stopped
BOOL PlayError; //Play completed with error
int TrackNummer; //Number of actual track
CCDAdress AbsSektor,RelSektor; //Startsector and Endsector of last/next Play
};
struct TTrackFlag
{
BYTE AudioChannels; //Amount of Audio Channels (2/4)
BOOL PreEmphasis; //Audio Channel with or without...
BOOL DataTrack; //Data track or Audio track
BOOL CopyProhibeted; //Digital copy prohibited
};
struct TTrackList
{
BYTE TrackNummer; //Number of Track
CCDAdress StartSektor; //First sector in HSG Format
long Laenge; //Amount of Sectors
TTrackFlag Flags;
};
struct TTrackListeMem
{
TTrackList Info;
TTrackListeMem *Prev,*Next;
};
struct TDriveInfo
{
int ID;
int LUN;
int HostAdapterNumber;
int Type;
int MaxSektors;
int SynchSektors;
int Mode;
char VendorID[9];
char ProductID[17];
int Speed;
int PerformDATest;
int SpinUpMode;
DWORD dwSpinUpTime;
BOOL bUseLastReadableAddress;
BOOL bUseC2ErrorInfo;
BOOL bSpinDown;
};
struct TJukeInfo
{
int ID;
int LUN;
int HostAdapterNumber;
int Type;
int MaxDrives;
int *pConnectedDrives;
int MaxDiscs;
char VendorID[9];
char ProductID[17];
};
// The class with the infos for the type mapping
class DACDLL CMapInfo
{
public:
CMapInfo();
char *GetTypName(int Index);
int GetTypMapping(int Index);
int GetTypMappingRev(int CDType);
private:
char TypNamen[MaxMappings][9];
int TypMapping[MaxMappings];
};
// The class with the infos for the type mapping
class DACDLL CMapInfoJuke
{
public:
CMapInfoJuke();
char *GetTypName(int Index);
int GetTypMapping(int Index);
int GetTypMappingRev(int JukeType);
private:
char TypNamen[MaxMappingsJuke][9];
int TypMapping[MaxMappingsJuke];
};
// The base class (pure virtual) for the CD access
class DACDLL CBaseCD
{
public:
int Lasterror();
virtual void PrepareCDDA()=0;
virtual void ReadCDDA(CCDAdress StartSektor,long Sektoranzahl,void *Buffer,BOOL bUseC2ErrorInfo=FALSE)=0;
virtual BOOL WaitCDDA(BOOL bImmediate=FALSE)=0;
virtual void FinishCDDA()=0;
virtual void SortWaveData(DWORD *Data,int Samples)=0;
virtual CCDAdress GetErrorAdress()=0;
virtual void Play_Audio(CCDAdress StartSektor,long Sektoranzahl)=0;
virtual void Stop_Audio()=0;
virtual void Pause_Audio()=0;
virtual void Resume_Audio()=0;
virtual TDriveStatus Get_DriveStatus()=0;
virtual BOOL MediaChanged()=0;
virtual void Get_MediaCatalogNumber(char szUPC[16])=0;
virtual void EjectDisk()=0;
virtual void LockDoor(int Lock)=0;
virtual void CloseTray()=0;
virtual void ReRead()=0;
virtual CCDAdress GetLastReadableAddress(CCDAdress StartSektor)=0;
virtual int GetMaxSektors()=0;
virtual int GetSynchSektors()=0;
virtual int GetMode()=0;
virtual int GetSpeed()=0;
virtual void InitSpeedTable()=0;
virtual BYTE GetSupportedSpeeds()=0;
virtual int GetCurrentSpeed()=0;
virtual void SetCurrentSpeed(int Speed)=0;
virtual int GetSpeed(BYTE Index)=0;
int ReadFirstTrackInfo(TTrackList &Infos);
int ReadNextTrackInfo(TTrackList &Infos);
int ReadPrevTrackInfo(TTrackList &Infos);
int ReadTrackInfo(TTrackList &Infos);
int ReadMaxTracks();
protected:
int Error,BusyFlag,DoneFlag;
TTrackListeMem *FirstTrack,*AktTrack;
void DeleteTrackList();
private:
CBaseCD& operator = (const CBaseCD &other);
};
// The class for the access to SCSI drives
class DACDLL CSCSICD:public CBaseCD
{
public:
CSCSICD (char drive, TDriveInfo &xInfo);
~CSCSICD();
virtual void PrepareCDDA();
virtual void ReadCDDA(CCDAdress StartSektor,long Sektoranzahl,void *Buffer,BOOL bUseC2ErrorInfo=FALSE);
virtual BOOL WaitCDDA(BOOL bImmediate=FALSE);
virtual void FinishCDDA();
virtual void SortWaveData(DWORD *Data,int Samples);
virtual CCDAdress GetErrorAdress();
virtual void Play_Audio(CCDAdress StartSektor,long Sektoranzahl);
virtual void Stop_Audio();
virtual void Pause_Audio();
virtual void Resume_Audio();
virtual TDriveStatus Get_DriveStatus();
virtual BOOL MediaChanged();
virtual TAudioStatus Get_AudioStatus_Info();
virtual void Get_MediaCatalogNumber(char szUPC[16]);
virtual void EjectDisk();
virtual void LockDoor(int Lock);
virtual void CloseTray();
virtual void ReRead();
virtual CCDAdress GetLastReadableAddress(CCDAdress StartSektor);
virtual int GetMaxSektors();
virtual int GetSynchSektors();
virtual int GetMode();
virtual int GetSpeed();
virtual void InitSpeedTable();
virtual BYTE GetSupportedSpeeds();
virtual int GetCurrentSpeed();
virtual void SetCurrentSpeed(int Speed);
virtual int GetSpeed(BYTE Index);
TDriveInfo &GetInfo()
{
return Config;
};
TSenseInfo GetSense();
TSenseInfo GetLastSenseInfo();
private:
CSCSICD& operator = (const CSCSICD &other);
TDriveInfo &Config; // Drive Configuration
BOOL CDPresentLast,Changed; // Helpvariables for the MediaChanged function
SRB_ExecSCSICmd ReadSRB; // SCSI Commando Block
TDriveMode ModeData;
BYTE NECRotationSpeed;
CMapInfo MapInfo;
DWORD StartReadTime;
int SpeedTable[256];
BYTE SupportedSpeeds;
HANDLE m_hDriveEvent;
TSenseInfo m_SenseInfo;
BOOL m_bSpeedTableInitialized;
};
// The base class for saving/converting the audio data
class DACDLL CBaseWave
{
public:
int Lasterror();
virtual void WritePuffer(long Samples,DWORD *Buffer)=0;
protected:
int Error; //last occured error
private:
CBaseWave& operator = (const CBaseWave &other);
};
typedef struct
{
BOOL bIsUsed; //Is Buffer used?
BOOL bReady; //Is Nuffer ready to write?
int nSamples; //Number of Samples in Buffer.
int nZeroSamples; //Number of Silence Samples to insert before the buffer
DWORD *dwBuffer; //Buffer for Audio Data
} WAVEBUFFER, *PWAVEBUFFER;
typedef struct _WAVEBUFFERLIST
{
PWAVEBUFFER pWaveBuffer;
_WAVEBUFFERLIST *pNext;
} WAVEBUFFERLIST, *PWAVEBUFFERLIST;
typedef struct
{
HANDLE hEvent;
LPVOID pData;
} TWAVEMTSTRUCT;
// The base class for saving/converting the audio data as its own thread
class DACDLL CBaseWaveMT
{
public:
CBaseWaveMT(DWORD dwBufferSize,BOOL bUseHighPriority=FALSE,int MaxSektors=27,DWORD dwExtraBytes=0);
~CBaseWaveMT();
void SetFadeInOut(int dwTotalSamples,int dwFadeSamples);
PWAVEBUFFER GetBuffer(); //returns NULL if no Buffer is available
void SignalBuffer(); //signal if a buffer is filled;
int Lasterror();
double GetBufferFullRatio();
DWORD GetBytesInBuffer();
virtual void WritePuffer(long Samples,DWORD *Buffer)=0;
friend unsigned _stdcall WaveThreadProc(LPVOID pUserData);
protected:
int Error; //last occured error
void StartThread(); //call this from your own initialisation function
BOOL WriteData();
void StopThread(BOOL bImmediate=FALSE); //call this from your own cleanup function
private:
CBaseWaveMT& operator = (const CBaseWaveMT &other);
DWORD m_Nullen[256];
PWAVEBUFFERLIST m_pFirstBuffer, m_pReadBuffer, m_pWriteBuffer;
TWAVEMTSTRUCT m_WaveInfo;
BOOL m_bStopThread,m_bAbortThread,m_bIsWorking;
HANDLE m_hWaveThread;
BOOL m_bUseHighPriority;
int m_dwTotalSamples,m_dwFadeSamples,m_dwCurrentSample;
int m_nBufferNum,m_nReadBufferNum,m_nWriteBufferNum;
int m_nMaxSektors;
};
// The class for saving audio data in a wave file
class DACDLL CWaveSave:public CBaseWave
{
public:
CWaveSave(const char *DateiName,BYTE Freq,BYTE Channels,BYTE Bits,BOOL bWriteHeaders=TRUE);
~CWaveSave();
virtual void WritePuffer(long Samples,DWORD *Buffer);
private:
void WMono8(long Samples,DWORD *Buffer);
void WStereo8(long Samples,DWORD *Buffer);
void WMono16(long Samples,DWORD *Buffer);
void WStereo16(long Samples,DWORD *Buffer);
void WLR8(long Samples,int Mode,DWORD *Buffer);
void WLR16(long Samples,int Mode,DWORD *Buffer);
CWaveSave& operator = (const CWaveSave &other);
BYTE ConvertType; //CodeNumber of the conversion type
FILE *Datei; //file variable to access the wave file
WORD *DPM16; //Pointer to the file data buffer
BYTE *DPM8; //Pointer to the file data buffer
DWORD *DPS16; //Pointer to the file data buffer
BYTE *DPS8; //Pointer to the file data buffer
int DatenCount; //Counter of data in buffer
long WaveBytes; //Counts all written bytes
BYTE SAdd; //Value to increment the source counter
BOOL m_bWriteHeaders; //Write Headers of Wave file
};
// The class for saving audio data in a wave file in its own thread
class DACDLL CWaveSaveMT:public CBaseWaveMT
{
public:
CWaveSaveMT(DWORD dwBufferSize,BOOL bUseHighPriority=FALSE,int MaxSektors=27,DWORD dwExtraBytes=0):CBaseWaveMT(dwBufferSize,bUseHighPriority,MaxSektors,dwExtraBytes)
{
};
void Init(const char *DateiName,BYTE Freq,BYTE Channels,BYTE Bits,BOOL bWriteHeaders=TRUE);
void Done(BOOL bImmediate=FALSE);
virtual void WritePuffer(long Samples,DWORD *Buffer);
private:
void WMono8(long Samples,DWORD *Buffer);
void WStereo8(long Samples,DWORD *Buffer);
void WMono16(long Samples,DWORD *Buffer);
void WStereo16(long Samples,DWORD *Buffer);
void WLR8(long Samples,int Mode,DWORD *Buffer);
void WLR16(long Samples,int Mode,DWORD *Buffer);
CWaveSave& operator = (const CWaveSave &other);
BYTE ConvertType; //CodeNumber of the conversion type
FILE *Datei; //file variable to access the wave file
WORD *DPM16; //Pointer to the file data buffer
BYTE *DPM8; //Pointer to the file data buffer
DWORD *DPS16; //Pointer to the file data buffer
BYTE *DPS8; //Pointer to the file data buffer
int DatenCount; //Counter of data in buffer
long WaveBytes; //Counts all written bytes
BYTE SAdd; //Value to increment the source counter
BOOL m_bWriteHeaders; //Write Headers of Wave file
};
// The class for copying the audio data from CD.
class DACDLL CDAC
{
public:
CDAC(CBaseCD *pDrive,CBaseWave *pWave,
CCDAdress Start,long Laenge,BOOL xKillZeros,BOOL bPerformDATest=TRUE,DWORD dwSpinUpTime=0,BOOL bUseLastReadableAddress=FALSE);
~CDAC();
int Lasterror();
void Copy();
int Errors();
void StopCopy();
// The following member functions are declared as virtual. They could be used to display
// information to the user. They do nothing by default.
virtual void WriteInit();
virtual void WritePercent(float Percent);
virtual void WriteReading();
virtual void WriteReadingEnd();
virtual void WriteSynch();
virtual void WriteSynchEnd();
virtual void WriteFlushing();
virtual void WriteFlushingEnd();
virtual void WriteSynchError();
virtual void WriteBufferUnderrun(CCDAdress Start);
virtual void WriteReRead(CCDAdress Start,long Laenge);
virtual void WriteSektorsSkipped(CCDAdress Start,long Laenge);
virtual void WriteDone();
virtual void OnIdle();
protected:
CCDAdress StartSektor,StartOld;
int SynchErrors,Error;
long Anzahl,AnzahlOld,Remain;
private:
CBaseCD *m_pCD;
BOOL RunCopy,KillFirst,KillLast,KillZero,Found;
DWORD m_dwSpinUpTime;
CBaseWave *m_pWaveSave;
long SektorAnzahl,Retries,SynchDiff,ZeroCount;
DWORD *MemBlocks[2];
int BlockCount,S_Offset;
int SpeedSave;
DWORD m_Nullen[256];
void ReadCDDA(CCDAdress Start,long Sektoranzahl,void *Buffer);
void FlushWave();
void FlushSynch(int Samples,DWORD *Data);
void MakeTable(DWORD *Werte,DWORD *Table);
int SynchSearch(DWORD *String1,DWORD *String2,DWORD *Table);
void SynchWave();
CDAC& operator = (const CDAC &other);
};
// The class for copying the audio data from CD.
class DACDLL CDACMT
{
public:
CDACMT(CBaseCD *pDrive,CBaseWaveMT *pWave,
CCDAdress Start,long Laenge,BOOL xKillZeros,BOOL bPerformDATest=TRUE,DWORD dwSpinUpTime=0,BOOL bUseHighPriority=FALSE,BOOL bUseC2ErrorInfo=FALSE,BOOL bSpinDown=FALSE,BOOL bUseLastReadableAddress=FALSE);
~CDACMT();
int Lasterror();
void Copy();
int Errors();
void StopCopy();
// The following member functions are declared as virtual. They could be used to display
// information to the user. They do nothing by default.
virtual void WriteInit();
virtual void WritePercent(float Percent);
virtual void WriteReading();
virtual void WriteReadingEnd();
virtual void WriteSynch();
virtual void WriteSynchEnd();
virtual void WriteFlushing();
virtual void WriteFlushingEnd();
virtual void WriteSynchError();
virtual void WriteBufferUnderrun(CCDAdress Start);
virtual void WriteReRead(CCDAdress Start,long Laenge);
virtual void WriteSektorsSkipped(CCDAdress Start,long Laenge);
virtual void WriteDone();
virtual void OnIdle(BOOL bReturnFast=TRUE);
friend unsigned _stdcall DACThreadProc(LPVOID pUserData);
protected:
CCDAdress StartSektor,StartOld;
int SynchErrors,Error;
long Anzahl,AnzahlOld,Remain;
void CopyMT();
private:
CBaseCD *m_pCD;
BOOL RunCopy,KillFirst,KillLast,KillZero,Found;
DWORD m_dwSpinUpTime;
CBaseWaveMT *m_pWaveSave;
BOOL m_bUseC2ErrorInfo;
BOOL m_bSpinDown;
long SektorAnzahl,Retries,SynchDiff,ZeroCount;
PWAVEBUFFER MemBlocks[2];
int BlockCount,S_Offset;
int SpeedSave;
int m_MaxSektors;
int m_SynchSektors;
void ReadCDDA(CCDAdress Start,long Sektoranzahl,void *Buffer);
void FlushWave(int nMax=2);
void FlushSynch(int Samples,PWAVEBUFFER Data);
void MakeTable(DWORD *Werte,DWORD *Table);
int SynchSearch(DWORD *String1,DWORD *String2,DWORD *Table);
void SynchWave();
CDACMT& operator = (const CDACMT &other);
HANDLE m_hDACThread;
BOOL m_bUseHighPriority;
};
// The class for configuring the SCSI CDROM drives
class DACDLL CMapDrive
{
public:
CMapDrive(BOOL bDoReset=TRUE);
~CMapDrive();
void Reset();
int GetMaxDrives();
TDriveInfo &GetInfo(int index);
BOOL GetInfoEx(int index, TDriveInfo *&pInfo);
void DeleteInfo(int index);
int GetMaxHostAdapters();
int GetSupportedHostAdapterMemory(int index);
void SetSupportedHostAdapterMemory(int index,int Memory);
int GetMaxSektors(int HostAdapterNumber);
protected:
void DeleteAll();
private:
struct TDriveInfoMem
{
TDriveInfo Info;
TDriveInfoMem *Next;
};
TDriveInfoMem *First;
int HostAdapterMemory[34];
HANDLE m_hDriveEvent;
};
// The class for configuring the SCSI Jukeboxes
class DACDLL CMapJuke
{
public:
CMapJuke(BOOL bDoReset=TRUE);
~CMapJuke();
void Reset();
int GetMaxJukes();
TJukeInfo &GetInfo(int index);
BOOL IsWorking(int index);
void SetWorking(int index,BOOL bIsWorking);
void DeleteInfo(int index);
protected:
void DeleteAll();
private:
struct TJukeInfoMem
{
TJukeInfo Info;
BOOL bIsWorking;
TJukeInfoMem *Next;
};
TJukeInfoMem *First;
HANDLE m_hJukeEvent;
};
//The class to access Jukeboxes
class DACDLL CJukeBox
{
public:
CJukeBox (TJukeInfo &xInfo);
~CJukeBox();
//use following defines to address an item in the jukebox:
//drive0..x : 0x4000...0x400x
//storage1..xxx : 0x0001...0x0xxx
BOOL MoveMedium(int Source,int Destination);
TJukeInfo &GetInfo()
{
return Config;
};
private:
TJukeInfo &Config; // Drive Configuration
CMapInfoJuke MapInfo;
HANDLE m_hJukeEvent;
};
// ----------------------
// function declarations
// ----------------------
// initialize and deinatialize the WNASPI32.DLL and some internal flags
int DACDLL LoadASPI();
int DACDLL FreeASPI();
int DACDLL CheckASPI();
#endif //_DAC32_H

View file

@ -0,0 +1,285 @@
# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
!IF "$(CFG)" == ""
CFG=Dac32 - Win32 Debug
!MESSAGE No configuration specified. Defaulting to Dac32 - Win32 Debug.
!ENDIF
!IF "$(CFG)" != "Dac32 - Win32 Release" && "$(CFG)" != "Dac32 - Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Dac32.mak" CFG="Dac32 - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Dac32 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Dac32 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "Dac32 - Win32 Debug"
CPP=cl.exe
RSC=rc.exe
MTL=mktyplib.exe
!IF "$(CFG)" == "Dac32 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "WinRel"
# PROP BASE Intermediate_Dir "WinRel"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
OUTDIR=.\Release
INTDIR=.\Release
ALL : "$(OUTDIR)\Dac32.dll" "$(OUTDIR)\Dac32.bsc"
CLEAN :
-@erase "$(INTDIR)\aspifunc.obj"
-@erase "$(INTDIR)\aspifunc.sbr"
-@erase "$(INTDIR)\dac32.obj"
-@erase "$(INTDIR)\dac32.res"
-@erase "$(INTDIR)\dac32.sbr"
-@erase "$(OUTDIR)\Dac32.bsc"
-@erase "$(OUTDIR)\Dac32.dll"
-@erase "$(OUTDIR)\Dac32.exp"
-@erase "$(OUTDIR)\Dac32.lib"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /YX /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "DLL" /Fr /YX /c
CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "DLL"\
/Fr"$(INTDIR)/" /Fp"$(INTDIR)/Dac32.pch" /YX /Fo"$(INTDIR)/" /c
CPP_OBJS=.\Release/
CPP_SBRS=.\Release/
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /win32
MTL_PROJ=/nologo /D "NDEBUG" /win32
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
RSC_PROJ=/l 0x407 /fo"$(INTDIR)/dac32.res" /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/Dac32.bsc"
BSC32_SBRS= \
"$(INTDIR)\aspifunc.sbr" \
"$(INTDIR)\dac32.sbr"
"$(OUTDIR)\Dac32.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# SUBTRACT LINK32 /map /nodefaultlib
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\
/pdb:"$(OUTDIR)/Dac32.pdb" /machine:I386 /out:"$(OUTDIR)/Dac32.dll"\
/implib:"$(OUTDIR)/Dac32.lib"
LINK32_OBJS= \
"$(INTDIR)\aspifunc.obj" \
"$(INTDIR)\dac32.obj" \
"$(INTDIR)\dac32.res"
"$(OUTDIR)\Dac32.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "Dac32 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "WinDebug"
# PROP BASE Intermediate_Dir "WinDebug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
OUTDIR=.\Debug
INTDIR=.\Debug
ALL : "$(OUTDIR)\Dac32.dll" "$(OUTDIR)\Dac32.bsc"
CLEAN :
-@erase "$(INTDIR)\aspifunc.obj"
-@erase "$(INTDIR)\aspifunc.sbr"
-@erase "$(INTDIR)\dac32.obj"
-@erase "$(INTDIR)\dac32.res"
-@erase "$(INTDIR)\dac32.sbr"
-@erase "$(INTDIR)\vc40.idb"
-@erase "$(INTDIR)\vc40.pdb"
-@erase "$(OUTDIR)\Dac32.bsc"
-@erase "$(OUTDIR)\Dac32.dll"
-@erase "$(OUTDIR)\Dac32.exp"
-@erase "$(OUTDIR)\Dac32.ilk"
-@erase "$(OUTDIR)\Dac32.lib"
-@erase "$(OUTDIR)\Dac32.pdb"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
# ADD BASE CPP /nologo /MT /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "DLL" /Fr /YX /c
CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS"\
/D "DLL" /Fr"$(INTDIR)/" /Fp"$(INTDIR)/Dac32.pch" /YX /Fo"$(INTDIR)/"\
/Fd"$(INTDIR)/" /c
CPP_OBJS=.\Debug/
CPP_SBRS=.\Debug/
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /win32
MTL_PROJ=/nologo /D "_DEBUG" /win32
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
RSC_PROJ=/l 0x407 /fo"$(INTDIR)/dac32.res" /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/Dac32.bsc"
BSC32_SBRS= \
"$(INTDIR)\aspifunc.sbr" \
"$(INTDIR)\dac32.sbr"
"$(OUTDIR)\Dac32.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# SUBTRACT LINK32 /nodefaultlib
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
odbccp32.lib /nologo /subsystem:windows /dll /incremental:yes\
/pdb:"$(OUTDIR)/Dac32.pdb" /debug /machine:I386 /out:"$(OUTDIR)/Dac32.dll"\
/implib:"$(OUTDIR)/Dac32.lib"
LINK32_OBJS= \
"$(INTDIR)\aspifunc.obj" \
"$(INTDIR)\dac32.obj" \
"$(INTDIR)\dac32.res"
"$(OUTDIR)\Dac32.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.c{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Target
# Name "Dac32 - Win32 Release"
# Name "Dac32 - Win32 Debug"
!IF "$(CFG)" == "Dac32 - Win32 Release"
!ELSEIF "$(CFG)" == "Dac32 - Win32 Debug"
!ENDIF
################################################################################
# Begin Source File
SOURCE=.\dac32.cpp
!IF "$(CFG)" == "Dac32 - Win32 Release"
DEP_CPP_DAC32=\
".\Aspifunc.h"\
".\Dac32.h"\
".\Scsidefs.h"\
".\Winaspi.h"\
"$(INTDIR)\dac32.obj" : $(SOURCE) $(DEP_CPP_DAC32) "$(INTDIR)"
"$(INTDIR)\dac32.sbr" : $(SOURCE) $(DEP_CPP_DAC32) "$(INTDIR)"
!ELSEIF "$(CFG)" == "Dac32 - Win32 Debug"
DEP_CPP_DAC32=\
".\Aspifunc.h"\
".\Dac32.h"\
".\Scsidefs.h"\
".\Winaspi.h"\
"$(INTDIR)\dac32.obj" : $(SOURCE) $(DEP_CPP_DAC32) "$(INTDIR)"
"$(INTDIR)\dac32.sbr" : $(SOURCE) $(DEP_CPP_DAC32) "$(INTDIR)"
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=.\aspifunc.cpp
DEP_CPP_ASPIF=\
".\Aspifunc.h"\
".\Scsidefs.h"\
".\Winaspi.h"\
"$(INTDIR)\aspifunc.obj" : $(SOURCE) $(DEP_CPP_ASPIF) "$(INTDIR)"
"$(INTDIR)\aspifunc.sbr" : $(SOURCE) $(DEP_CPP_ASPIF) "$(INTDIR)"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\dac32.rc
"$(INTDIR)\dac32.res" : $(SOURCE) "$(INTDIR)"
$(RSC) $(RSC_PROJ) $(SOURCE)
# End Source File
# End Target
# End Project
################################################################################

View file

@ -0,0 +1,121 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Neutral resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
#ifdef _WIN32
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,5,11
PRODUCTVERSION 1,4,5,11
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "CASH\0"
VALUE "FileDescription", "Christoph Schmelnik's Digital Audio Copy 32 Bit Copy Engine\0"
VALUE "FileVersion", "1, 4, 5, 11\0"
VALUE "InternalName", "DAC32 DLL\0"
VALUE "LegalCopyright", "Copyright © 1996-1999 by Christoph Schmelnik\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "Dac32.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Christoph Schmelnik's Digital Audio Copy for Win32\0"
VALUE "ProductVersion", "Version 1.45\0"
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END
#endif // !_MAC
#endif // Neutral resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Deutsch (Deutschland) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
#ifdef _WIN32
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // Deutsch (Deutschland) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View file

@ -0,0 +1,501 @@
#include <stdio.h>
#include <stddef.h>
#include "NTScsi.h"
typedef struct {
BYTE ha;
BYTE tgt;
BYTE lun;
BYTE driveLetter;
BOOL bUsed;
HANDLE hDevice;
BYTE inqData[36];
} NTSCSIDRIVE;
typedef struct
{
BYTE numAdapters;
NTSCSIDRIVE drive[26];
} NTSCSIDRIVES;
void GetDriveInformation( BYTE i, NTSCSIDRIVE *pDrive );
static HANDLE GetFileHandle( BYTE i );
static BOOL bNtScsiAvailable = FALSE;
static NTSCSIDRIVES NtScsiDrives;
static BOOL bUseNtScsi = FALSE;
/*
* Initialization of SCSI Pass Through Interface code. Responsible for
* setting up the array of SCSI devices. This code will be a little
* different from the normal code -- it will query each drive letter from
* C: through Z: to see if it is a CD. When we identify a CD, we then
* send CDB with the INQUIRY command to it -- NT will automagically fill in
* the PathId, TargetId, and Lun for us.
*/
int NtScsiInit( void )
{
BYTE i;
wchar_t buf[4] = {0};
UINT uDriveType;
int retVal = 0;
if ( bNtScsiAvailable )
{
for( i = 2; i < 26; i++ ) if ( NtScsiDrives.drive[i].bUsed ) retVal++;
bUseNtScsi = (retVal > 0 );
return retVal;
}
memset( &NtScsiDrives, 0x00, sizeof(NtScsiDrives) );
for( i = 0; i < 26; i++ )
{
NtScsiDrives.drive[i].hDevice = INVALID_HANDLE_VALUE;
}
for( i = 2; i < 26; i++ )
{
wsprintf( buf, L"%c:\\", (wchar_t)('A'+i) );
uDriveType = GetDriveType( buf );
/* check if this is a CDROM drive */
if ( uDriveType == DRIVE_CDROM )
{
GetDriveInformation( i, &NtScsiDrives.drive[i] );
if ( NtScsiDrives.drive[i].bUsed )
retVal++;
}
}
NtScsiDrives.numAdapters = NtScsiGetNumAdapters( );
bNtScsiAvailable = TRUE;
if ( retVal > 0 )
{
bUseNtScsi = TRUE;
}
return retVal;
}
int NtScsiDeInit( void )
{
BYTE i;
if ( !bNtScsiAvailable )
return 0;
for( i = 2; i < 26; i++ )
{
if ( NtScsiDrives.drive[i].bUsed )
{
CloseHandle( NtScsiDrives.drive[i].hDevice );
}
}
NtScsiDrives.numAdapters = NtScsiGetNumAdapters( );
ZeroMemory( &NtScsiDrives, sizeof(NtScsiDrives) );
bNtScsiAvailable = FALSE;
return -1;
}
/*
* Returns the number of "adapters" present.
*/
BYTE NtScsiGetNumAdapters( void )
{
BYTE buf[256] = {0};
WORD i;
BYTE numAdapters = 0;
// PortNumber 0 should exist, so pre-mark it. This avoids problems
// when the primary IDE drives are on PortNumber 0, but can't be opened
// because of insufficient privelege (ie. non-admin).
buf[0] = 1;
for( i = 0; i < 26; i++ )
{
if ( NtScsiDrives.drive[i].bUsed )
buf[NtScsiDrives.drive[i].ha] = 1;
}
for( i = 0; i <= 255; i++ )
{
if ( buf[i] )
numAdapters++;
}
return numAdapters;
}
/*
* Replacement for GetASPI32SupportInfo from wnaspi32.dll
*/
DWORD NtScsiGetASPI32SupportInfo( void )
{
DWORD retVal;
if ( !NtScsiDrives.numAdapters )
retVal = (DWORD)(MAKEWORD(0,SS_NO_ADAPTERS));
else
retVal = (DWORD)(MAKEWORD(NtScsiDrives.numAdapters,SS_COMP));
return retVal;
}
/*
* Needs to call the appropriate function for the lpsrb->SRB_Cmd specified.
* Valid types are SC_HA_INQUIRY, SC_GET_DEV_TYPE, SC_EXEC_SCSI_CMD,
* and SC_RESET_DEV.
*/
DWORD NtScsiSendASPI32Command( LPSRB lpsrb )
{
if ( !lpsrb )
return SS_ERR;
switch( lpsrb->SRB_Cmd )
{
case SC_HA_INQUIRY:
return NtScsiHandleHaInquiry( (LPSRB_HAINQUIRY)lpsrb );
break;
case SC_GET_DEV_TYPE:
return NtScsiGetDeviceType( (LPSRB_GDEVBLOCK)lpsrb );
break;
case SC_EXEC_SCSI_CMD:
return NtScsiExecSCSICommand( (LPSRB_EXECSCSICMD)lpsrb, FALSE );
break;
case SC_RESET_DEV:
default:
lpsrb->SRB_Status = SS_ERR;
return SS_ERR;
break;
}
return SS_ERR; // should never get to here...
}
/*
* Universal function to get a file handle to the CD device. Since
* NT 4.0 wants just the GENERIC_READ flag, and Win2K wants both
* GENERIC_READ and GENERIC_WRITE (why a read-only CD device needs
* GENERIC_WRITE access is beyond me...), the easist workaround is to just
* try them both.
*/
static HANDLE GetFileHandle( BYTE i )
{
wchar_t buf[12] = {0};
HANDLE fh = NULL;
OSVERSIONINFO osver;
DWORD dwFlags;
memset( &osver, 0x00, sizeof(osver) );
osver.dwOSVersionInfoSize = sizeof(osver);
GetVersionEx( &osver );
// if Win2K or greater, add GENERIC_WRITE
dwFlags = GENERIC_READ;
if ( (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osver.dwMajorVersion > 4) )
{
dwFlags |= GENERIC_WRITE;
}
wsprintf( buf, L"\\\\.\\%c:", (wchar_t)('A'+i) );
fh = CreateFile( buf, dwFlags, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING, 0, NULL );
if ( fh == INVALID_HANDLE_VALUE )
{
// it went foobar somewhere, so try it with the GENERIC_WRITE bit flipped
dwFlags ^= GENERIC_WRITE;
fh = CreateFile( buf, dwFlags, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
}
if ( fh == INVALID_HANDLE_VALUE )
{
}
else
{
}
return fh;
}
/*
* fills in a pDrive structure with information from a SCSI_INQUIRY
* and obtains the ha:tgt:lun values via IOCTL_SCSI_GET_ADDRESS
*/
void GetDriveInformation( BYTE i, NTSCSIDRIVE *pDrive )
{
HANDLE fh;
char buf[2048] = {0};
BOOL status;
PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER pswb;
PSCSI_ADDRESS pscsiAddr;
ULONG length, returned;
BYTE inqData[100] = {0};
fh = GetFileHandle( i );
if ( fh == INVALID_HANDLE_VALUE )
{
return;
}
/*
* Get the drive inquiry data
*/
ZeroMemory( &buf, 2048 );
ZeroMemory( inqData, 100 );
pswb = (PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER)buf;
pswb->spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
pswb->spt.CdbLength = 6;
pswb->spt.SenseInfoLength = 24;
pswb->spt.DataIn = SCSI_IOCTL_DATA_IN;
pswb->spt.DataTransferLength = 100;
pswb->spt.TimeOutValue = 2;
pswb->spt.DataBuffer = inqData;
pswb->spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,ucSenseBuf );
pswb->spt.Cdb[0] = 0x12;
pswb->spt.Cdb[4] = 100;
length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);
status = DeviceIoControl( fh,
IOCTL_SCSI_PASS_THROUGH_DIRECT,
pswb,
length,
pswb,
length,
&returned,
NULL );
if ( !status )
{
CloseHandle( fh );
return;
}
memcpy( pDrive->inqData, inqData, 36 );
/*
* get the address (path/tgt/lun) of the drive via IOCTL_SCSI_GET_ADDRESS
*/
ZeroMemory( &buf, 2048 );
pscsiAddr = (PSCSI_ADDRESS)buf;
pscsiAddr->Length = sizeof(SCSI_ADDRESS);
if ( DeviceIoControl( fh, IOCTL_SCSI_GET_ADDRESS, NULL, 0,
pscsiAddr, sizeof(buf), &returned,
NULL ) )
{
pDrive->bUsed = TRUE;
pDrive->ha = pscsiAddr->PortNumber;
pDrive->tgt = pscsiAddr->TargetId;
pDrive->lun = pscsiAddr->Lun;
pDrive->driveLetter = i;
pDrive->hDevice = INVALID_HANDLE_VALUE;
}
else if (50 == GetLastError()) // usb/firewire
{
pDrive->bUsed = TRUE;
pDrive->ha = i;
pDrive->tgt = 0;
pDrive->lun = 0;
pDrive->driveLetter = i;
pDrive->hDevice = INVALID_HANDLE_VALUE;
}
else
{
pDrive->bUsed = FALSE;
}
CloseHandle( fh );
}
DWORD NtScsiHandleHaInquiry( LPSRB_HAINQUIRY lpsrb )
{
DWORD *pMTL;
lpsrb->HA_Count = NtScsiDrives.numAdapters;
if ( lpsrb->SRB_HaId >= NtScsiDrives.numAdapters )
{
lpsrb->SRB_Status = SS_INVALID_HA;
return SS_INVALID_HA;
}
lpsrb->HA_SCSI_ID = 7; // who cares... we're not really an ASPI manager
memcpy( lpsrb->HA_ManagerId, "blahblahblahblah", 16 );
memcpy( lpsrb->HA_Identifier, "blahblahblahblah", 16 );
lpsrb->HA_Identifier[13] = (char)('0'+lpsrb->SRB_HaId);
ZeroMemory( lpsrb->HA_Unique, 16 );
lpsrb->HA_Unique[3] = 8;
pMTL = (LPDWORD)&lpsrb->HA_Unique[4];
*pMTL = 64 * 1024;
lpsrb->SRB_Status = SS_COMP;
return SS_COMP;
}
/*
* Scans through the drive array and returns DTYPE_CDROM type for all items
* found, and DTYPE_UNKNOWN for all others.
*/
DWORD NtScsiGetDeviceType( LPSRB_GDEVBLOCK lpsrb )
{
lpsrb->SRB_Status = SS_NO_DEVICE;
if ( NtScsiGetDeviceIndex( lpsrb->SRB_HaId, lpsrb->SRB_Target, lpsrb->SRB_Lun ) )
lpsrb->SRB_Status = SS_COMP;
if ( lpsrb->SRB_Status == SS_COMP )
lpsrb->SRB_DeviceType = DTC_CDROM;
else
lpsrb->SRB_DeviceType = DTC_UNKNOWN;
return lpsrb->SRB_Status;
}
/*
* Looks up the index in the drive array for a given ha:tgt:lun triple
*/
BYTE NtScsiGetDeviceIndex( BYTE ha, BYTE tgt, BYTE lun )
{
BYTE i;
for( i = 2; i < 26; i++ )
{
if ( NtScsiDrives.drive[i].bUsed )
{
NTSCSIDRIVE *lpd;
lpd = &NtScsiDrives.drive[i];
if ( (lpd->ha == ha) && (lpd->tgt == tgt) && (lpd->lun == lun) )
return i;
}
}
return 0;
}
/*
* Converts ASPI-style SRB to SCSI Pass Through IOCTL
*/
DWORD NtScsiExecSCSICommand( LPSRB_EXECSCSICMD lpsrb, BOOL bBeenHereBefore )
{
BOOL status;
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb;
ULONG length, returned;
BYTE idx;
idx = NtScsiGetDeviceIndex( lpsrb->SRB_HaId, lpsrb->SRB_Target, lpsrb->SRB_Lun );
if ( idx == 0 )
{
lpsrb->SRB_Status = SS_ERR;
return SS_ERR;
}
if ( lpsrb->CDBByte[0] == 0x12 ) // is it an INQUIRY?
{
lpsrb->SRB_Status = SS_COMP;
memcpy( lpsrb->SRB_BufPointer, NtScsiDrives.drive[idx].inqData, 36 );
return SS_COMP;
}
if ( NtScsiDrives.drive[idx].hDevice == INVALID_HANDLE_VALUE )
NtScsiDrives.drive[idx].hDevice = GetFileHandle( NtScsiDrives.drive[idx].driveLetter );
ZeroMemory( &swb, sizeof(swb) );
swb.spt.Length = sizeof(SCSI_PASS_THROUGH);
swb.spt.CdbLength = lpsrb->SRB_CDBLen;
if ( lpsrb->SRB_Flags & SRB_DIR_IN )
swb.spt.DataIn = SCSI_IOCTL_DATA_IN;
else if ( lpsrb->SRB_Flags & SRB_DIR_OUT )
swb.spt.DataIn = SCSI_IOCTL_DATA_OUT;
else
swb.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
swb.spt.DataTransferLength = lpsrb->SRB_BufLen;
swb.spt.TimeOutValue = 5;
swb.spt.DataBuffer = lpsrb->SRB_BufPointer;
swb.spt.SenseInfoOffset =
offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf );
memcpy( swb.spt.Cdb, lpsrb->CDBByte, lpsrb->SRB_CDBLen );
length = sizeof(swb);
status = DeviceIoControl( NtScsiDrives.drive[idx].hDevice,
IOCTL_SCSI_PASS_THROUGH_DIRECT,
&swb,
length,
&swb,
length,
&returned,
NULL );
if ( status )
{
lpsrb->SRB_Status = SS_COMP;
}
else
{
DWORD dwErrCode;
lpsrb->SRB_Status = SS_ERR;
lpsrb->SRB_TargStat = 0x0004;
dwErrCode = GetLastError();
/*
* KLUDGE ALERT! KLUDGE ALERT! KLUDGE ALERT!
* Whenever a disk changer switches disks, it may render the device
* handle invalid. We try to catch these errors here and recover
* from them.
*/
if ( !bBeenHereBefore &&
((dwErrCode == ERROR_MEDIA_CHANGED) || (dwErrCode == ERROR_INVALID_HANDLE)) )
{
if ( dwErrCode != ERROR_INVALID_HANDLE )
CloseHandle( NtScsiDrives.drive[idx].hDevice );
GetDriveInformation( idx, &NtScsiDrives.drive[idx] );
return NtScsiExecSCSICommand( lpsrb, TRUE );
}
}
return lpsrb->SRB_Status;
}
BOOL UsingSCSIPT( void )
{
return bUseNtScsi;
}
/*
* Calls GetFileHandle for the CD refered to by ha:tgt:lun to open it for
* use
*/
void NtScsiOpenCDHandle( BYTE ha, BYTE tgt, BYTE lun )
{
BYTE idx;
idx = NtScsiGetDeviceIndex( ha, tgt, lun );
if ( idx && NtScsiDrives.drive[idx].hDevice == INVALID_HANDLE_VALUE )
NtScsiDrives.drive[idx].hDevice = GetFileHandle( NtScsiDrives.drive[idx].driveLetter );
}

View file

@ -0,0 +1,147 @@
/*
* distilled information from various header files from Microsoft's
* DDK for Windows NT 4.0
*/
#ifndef NTSCSI_H_INCLUDED
#define NTSCSI_H_INCLUDED
#include <windows.h>
#include "Aspi.h"
typedef struct {
USHORT Length;
UCHAR ScsiStatus;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
UCHAR CdbLength;
UCHAR SenseInfoLength;
UCHAR DataIn;
ULONG DataTransferLength;
ULONG TimeOutValue;
ULONG DataBufferOffset;
ULONG SenseInfoOffset;
UCHAR Cdb[16];
} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;
typedef struct {
USHORT Length;
UCHAR ScsiStatus;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
UCHAR CdbLength;
UCHAR SenseInfoLength;
UCHAR DataIn;
ULONG DataTransferLength;
ULONG TimeOutValue;
PVOID DataBuffer;
ULONG SenseInfoOffset;
UCHAR Cdb[16];
} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
typedef struct {
SCSI_PASS_THROUGH spt;
ULONG Filler;
UCHAR ucSenseBuf[32];
UCHAR ucDataBuf[512];
} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS;
typedef struct {
SCSI_PASS_THROUGH_DIRECT spt;
ULONG Filler;
UCHAR ucSenseBuf[32];
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
typedef struct {
UCHAR NumberOfLogicalUnits;
UCHAR InitiatorBusId;
ULONG InquiryDataOffset;
} SCSI_BUS_DATA, *PSCSI_BUS_DATA;
typedef struct {
UCHAR NumberOfBusses;
SCSI_BUS_DATA BusData[1];
} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO;
typedef struct {
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
BOOLEAN DeviceClaimed;
ULONG InquiryDataLength;
ULONG NextInquiryDataOffset;
UCHAR InquiryData[1];
} SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA;
typedef struct {
ULONG Length;
UCHAR PortNumber;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
} SCSI_ADDRESS, *PSCSI_ADDRESS;
/*
* method codes
*/
#define METHOD_BUFFERED 0
#define METHOD_IN_DIRECT 1
#define METHOD_OUT_DIRECT 2
#define METHOD_NEITHER 3
/*
* file access values
*/
#define FILE_ANY_ACCESS 0
#ifndef FILE_READ_ACCESS
#define FILE_READ_ACCESS (0x0001)
#define FILE_WRITE_ACCESS (0x0002)
#endif
#define IOCTL_SCSI_BASE 0x00000004
/*
* constants for DataIn member of SCSI_PASS_THROUGH* structures
*/
#define SCSI_IOCTL_DATA_OUT 0
#define SCSI_IOCTL_DATA_IN 1
#define SCSI_IOCTL_DATA_UNSPECIFIED 2
/*
* Standard IOCTL define
*/
#define CTL_CODE( DevType, Function, Method, Access ) ( \
((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)
#define IOCTL_SCSI_PASS_THROUGH CTL_CODE( IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
#define IOCTL_SCSI_MINIPORT CTL_CODE( IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE( IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE( IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE( IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
#define IOCTL_SCSI_GET_ADDRESS CTL_CODE( IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS )
int NtScsiInit( void );
int NtScsiDeInit( void );
BYTE NtScsiGetNumAdapters( void );
DWORD NtScsiGetASPI32SupportInfo( void );
DWORD NtScsiGetDeviceType( LPSRB_GDEVBLOCK lpsrb );
BYTE NtScsiGetDeviceIndex( BYTE ha, BYTE tgt, BYTE lun );
DWORD NtScsiHandleHaInquiry( LPSRB_HAINQUIRY lpsrb );
extern "C" DWORD NtScsiSendASPI32Command( LPSRB lpsrb );
DWORD NtScsiExecSCSICommand( LPSRB_EXECSCSICMD lpsrb, BOOL bBeenHereBefore );
#endif

View file

@ -0,0 +1,17 @@
#if USE_WINDAC
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by dac32.rc
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
#endif

View file

@ -0,0 +1,252 @@
//**********************************************************************
//
// Name: SCSIDEFS.H
//
// Description: SCSI definitions ('C' Language)
//
//**********************************************************************
//**********************************************************************
// %%% TARGET STATUS VALUES %%%
//**********************************************************************
#define STATUS_GOOD 0x00 // Status Good
#define STATUS_CHKCOND 0x02 // Check Condition
#define STATUS_CONDMET 0x04 // Condition Met
#define STATUS_BUSY 0x08 // Busy
#define STATUS_INTERM 0x10 // Intermediate
#define STATUS_INTCDMET 0x14 // Intermediate-condition met
#define STATUS_RESCONF 0x18 // Reservation conflict
#define STATUS_COMTERM 0x22 // Command Terminated
#define STATUS_QFULL 0x28 // Queue full
//**********************************************************************
// %%% SCSI MISCELLANEOUS EQUATES %%%
//**********************************************************************
#define MAXLUN 7 // Maximum Logical Unit Id
#define MAXTARG 7 // Maximum Target Id
#define MAX_SCSI_LUNS 64 // Maximum Number of SCSI LUNs
#define MAX_NUM_HA 8 // Maximum Number of SCSI HA's
///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
//
// %%% SCSI COMMAND OPCODES %%%
//
///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
//**********************************************************************
// %%% Commands for all Device Types %%%
//**********************************************************************
#define SCSI_CHANGE_DEF 0x40 // Change Definition (Optional)
#define SCSI_COMPARE 0x39 // Compare (O)
#define SCSI_COPY 0x18 // Copy (O)
#define SCSI_COP_VERIFY 0x3A // Copy and Verify (O)
#define SCSI_INQUIRY 0x12 // Inquiry (MANDATORY)
#define SCSI_LOG_SELECT 0x4C // Log Select (O)
#define SCSI_LOG_SENSE 0x4D // Log Sense (O)
#define SCSI_MODE_SEL6 0x15 // Mode Select 6-byte (Device Specific)
#define SCSI_MODE_SEL10 0x55 // Mode Select 10-byte (Device Specific)
#define SCSI_MODE_SEN6 0x1A // Mode Sense 6-byte (Device Specific)
#define SCSI_MODE_SEN10 0x5A // Mode Sense 10-byte (Device Specific)
#define SCSI_READ_BUFF 0x3C // Read Buffer (O)
#define SCSI_REQ_SENSE 0x03 // Request Sense (MANDATORY)
#define SCSI_SEND_DIAG 0x1D // Send Diagnostic (O)
#define SCSI_RCV_DIAG 0x1C // Receive Diagnostic Results (O)
#define SCSI_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY)
#define SCSI_WRITE_BUFF 0x3B // Write Buffer (O)
//**********************************************************************
// %%% Commands Unique to Direct Access Devices %%%
//**********************************************************************
#define SCSI_FORMAT 0x04 // Format Unit (MANDATORY)
#define SCSI_LCK_UN_CAC 0x36 // Lock Unlock Cache (O)
#define SCSI_PREFETCH 0x34 // Prefetch (O)
#define SCSI_MED_REMOVL 0x1E // Prevent/Allow medium Removal (O)
#define SCSI_READ6 0x08 // Read 6-byte (MANDATORY)
#define SCSI_READ10 0x28 // Read 10-byte (MANDATORY)
#define SCSI_RD_CAPAC 0x25 // Read Capacity (MANDATORY)
#define SCSI_RD_DEFECT 0x37 // Read Defect Data (O)
#define SCSI_READ_LONG 0x3E // Read Long (O)
#define SCSI_REASS_BLK 0x07 // Reassign Blocks (O)
#define SCSI_RELEASE 0x17 // Release Unit (MANDATORY)
#define SCSI_RESERVE 0x16 // Reserve Unit (MANDATORY)
#define SCSI_REZERO 0x01 // Rezero Unit (O)
#define SCSI_SRCH_DAT_E 0x31 // Search Data Equal (O)
#define SCSI_SRCH_DAT_H 0x30 // Search Data High (O)
#define SCSI_SRCH_DAT_L 0x32 // Search Data Low (O)
#define SCSI_SEEK6 0x0B // Seek 6-Byte (O)
#define SCSI_SEEK10 0x2B // Seek 10-Byte (O)
#define SCSI_SET_LIMIT 0x33 // Set Limits (O)
#define SCSI_START_STP 0x1B // Start/Stop Unit (O)
#define SCSI_SYNC_CACHE 0x35 // Synchronize Cache (O)
#define SCSI_VERIFY 0x2F // Verify (O)
#define SCSI_WRITE6 0x0A // Write 6-Byte (MANDATORY)
#define SCSI_WRITE10 0x2A // Write 10-Byte (MANDATORY)
#define SCSI_WRT_VERIFY 0x2E // Write and Verify (O)
#define SCSI_WRITE_LONG 0x3F // Write Long (O)
#define SCSI_WRITE_SAME 0x41 // Write Same (O)
//**********************************************************************
// %%% Commands Unique to Sequential Access Devices %%%
//**********************************************************************
#define SCSI_ERASE 0x19 // Erase (MANDATORY)
#define SCSI_LOAD_UN 0x1B // Load/Unload (O)
#define SCSI_LOCATE 0x2B // Locate (O)
#define SCSI_RD_BLK_LIM 0x05 // Read Block Limits (MANDATORY)
#define SCSI_READ_POS 0x34 // Read Position (O)
#define SCSI_READ_REV 0x0F // Read Reverse (O)
#define SCSI_REC_BF_DAT 0x14 // Recover Buffer Data (O)
#define SCSI_REWIND 0x01 // Rewind (MANDATORY)
#define SCSI_SPACE 0x11 // Space (MANDATORY)
#define SCSI_VERIFY_T 0x13 // Verify (Tape) (O)
#define SCSI_WRT_FILE 0x10 // Write Filemarks (MANDATORY)
#define SCSI_PARTITION 0x0D // DAT/QFA Partition Select
#define SCSI_READWRITE 0x06 // Set Read/Write Parameters
//**********************************************************************
// %%% Commands Unique to Printer Devices %%%
//**********************************************************************
#define SCSI_PRINT 0x0A // Print (MANDATORY)
#define SCSI_SLEW_PNT 0x0B // Slew and Print (O)
#define SCSI_STOP_PNT 0x1B // Stop Print (O)
#define SCSI_SYNC_BUFF 0x10 // Synchronize Buffer (O)
//**********************************************************************
// %%% Commands Unique to Processor Devices %%%
//**********************************************************************
#define SCSI_RECEIVE 0x08 // Receive (O)
#define SCSI_SEND 0x0A // Send (O)
//**********************************************************************
// %%% Commands Unique to Write-Once Devices %%%
//**********************************************************************
#define SCSI_MEDIUM_SCN 0x38 // Medium Scan (O)
#define SCSI_SRCHDATE10 0x31 // Search Data Equal 10-Byte (O)
#define SCSI_SRCHDATE12 0xB1 // Search Data Equal 12-Byte (O)
#define SCSI_SRCHDATH10 0x30 // Search Data High 10-Byte (O)
#define SCSI_SRCHDATH12 0xB0 // Search Data High 12-Byte (O)
#define SCSI_SRCHDATL10 0x32 // Search Data Low 10-Byte (O)
#define SCSI_SRCHDATL12 0xB2 // Search Data Low 12-Byte (O)
#define SCSI_SET_LIM_10 0x33 // Set Limits 10-Byte (O)
#define SCSI_SET_LIM_12 0xB3 // Set Limits 10-Byte (O)
#define SCSI_VERIFY10 0x2F // Verify 10-Byte (O)
#define SCSI_VERIFY12 0xAF // Verify 12-Byte (O)
#define SCSI_WRITE12 0xAA // Write 12-Byte (O)
#define SCSI_WRT_VER10 0x2E // Write and Verify 10-Byte (O)
#define SCSI_WRT_VER12 0xAE // Write and Verify 12-Byte (O)
//**********************************************************************
// %%% Commands Unique to CD-ROM Devices %%%
//**********************************************************************
#define SCSI_PLAYAUD_10 0x45 // Play Audio 10-Byte (O)
#define SCSI_PLAYAUD_12 0xA5 // Play Audio 12-Byte 12-Byte (O)
#define SCSI_PLAYAUDMSF 0x47 // Play Audio MSF (O)
#define SCSI_PLAYA_TKIN 0x48 // Play Audio Track/Index (O)
#define SCSI_PLYTKREL10 0x49 // Play Track Relative 10-Byte (O)
#define SCSI_PLYTKREL12 0xA9 // Play Track Relative 12-Byte (O)
#define SCSI_READCDCAP 0x25 // Read CD-ROM Capacity (MANDATORY)
#define SCSI_READHEADER 0x44 // Read Header (O)
#define SCSI_SUBCHANNEL 0x42 // Read Subchannel (O)
#define SCSI_READ_TOC 0x43 // Read TOC (O)
//**********************************************************************
// %%% Commands Unique to Scanner Devices %%%
//**********************************************************************
#define SCSI_GETDBSTAT 0x34 // Get Data Buffer Status (O)
#define SCSI_GETWINDOW 0x25 // Get Window (O)
#define SCSI_OBJECTPOS 0x31 // Object Position (O)
#define SCSI_SCAN 0x1B // Scan (O)
#define SCSI_SETWINDOW 0x24 // Set Window (MANDATORY)
//**********************************************************************
// %%% Commands Unique to Optical Memory Devices %%%
//**********************************************************************
#define SCSI_UpdateBlk 0x3D // Update Block (O)
//**********************************************************************
// %%% Commands Unique to Medium Changer Devices %%%
//**********************************************************************
#define SCSI_EXCHMEDIUM 0xA6 // Exchange Medium (O)
#define SCSI_INITELSTAT 0x07 // Initialize Element Status (O)
#define SCSI_POSTOELEM 0x2B // Position to Element (O)
#define SCSI_REQ_VE_ADD 0xB5 // Request Volume Element Address (O)
#define SCSI_SENDVOLTAG 0xB6 // Send Volume Tag (O)
//**********************************************************************
// %%% Commands Unique to Communication Devices %%%
//**********************************************************************
#define SCSI_GET_MSG_6 0x08 // Get Message 6-Byte (MANDATORY)
#define SCSI_GET_MSG_10 0x28 // Get Message 10-Byte (O)
#define SCSI_GET_MSG_12 0xA8 // Get Message 12-Byte (O)
#define SCSI_SND_MSG_6 0x0A // Send Message 6-Byte (MANDATORY)
#define SCSI_SND_MSG_10 0x2A // Send Message 10-Byte (O)
#define SCSI_SND_MSG_12 0xAA // Send Message 12-Byte (O)
///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
//
// %%% END OF SCSI COMMAND OPCODES %%%
//
///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
//**********************************************************************
// %%% Request Sense Data Format %%%
//**********************************************************************
typedef struct {
BYTE ErrorCode; // Error Code (70H or 71H)
BYTE SegmentNum; // Number of current segment descriptor
BYTE SenseKey; // Sense Key(See bit definitions too)
BYTE InfoByte0; // Information MSB
BYTE InfoByte1; // Information MID
BYTE InfoByte2; // Information MID
BYTE InfoByte3; // Information LSB
BYTE AddSenLen; // Additional Sense Length
BYTE ComSpecInf0; // Command Specific Information MSB
BYTE ComSpecInf1; // Command Specific Information MID
BYTE ComSpecInf2; // Command Specific Information MID
BYTE ComSpecInf3; // Command Specific Information LSB
BYTE AddSenseCode; // Additional Sense Code
BYTE AddSenQual; // Additional Sense Code Qualifier
// BYTE FieldRepUCode; // Field Replaceable Unit Code
// BYTE SenKeySpec15; // Sense Key Specific 15th byte
// BYTE SenKeySpec16; // Sense Key Specific 16th byte
// BYTE SenKeySpec17; // Sense Key Specific 17th byte
// BYTE AddSenseBytes; // Additional Sense Bytes
} SENSE_DATA_FMT;
//**********************************************************************
// %%% REQUEST SENSE ERROR CODE %%%
//**********************************************************************
#define SERROR_CURRENT 0x70 // Current Errors
#define SERROR_DEFERED 0x71 // Deferred Errors
//**********************************************************************
// %%% REQUEST SENSE BIT DEFINITIONS %%%
//**********************************************************************
#define SENSE_VALID 0x80 // Byte 0 Bit 7
#define SENSE_FILEMRK 0x80 // Byte 2 Bit 7
#define SENSE_EOM 0x40 // Byte 2 Bit 6
#define SENSE_ILI 0x20 // Byte 2 Bit 5
//**********************************************************************
// %%% REQUEST SENSE SENSE KEY DEFINITIONS %%%
//**********************************************************************
#define KEY_NOSENSE 0x00 // No Sense
#define KEY_RECERROR 0x01 // Recovered Error
#define KEY_NOTREADY 0x02 // Not Ready
#define KEY_MEDIUMERR 0x03 // Medium Error
#define KEY_HARDERROR 0x04 // Hardware Error
#define KEY_ILLGLREQ 0x05 // Illegal Request
#define KEY_UNITATT 0x06 // Unit Attention
#define KEY_DATAPROT 0x07 // Data Protect
#define KEY_BLANKCHK 0x08 // Blank Check
#define KEY_VENDSPEC 0x09 // Vendor Specific
#define KEY_COPYABORT 0x0A // Copy Abort
#define KEY_ABORT 0x0B // Abort
#define KEY_EQUAL 0x0C // Equal (Search)
#define KEY_VOLOVRFLW 0x0D // Volume Overflow
#define KEY_MISCOMP 0x0E // Miscompare (Search)
#define KEY_RESERVED 0x0F // Reserved
//**********************************************************************
// %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%%
//**********************************************************************
#define DTYPE_DASD 0x00 // Disk Device
#define DTYPE_SEQD 0x01 // Tape Device
#define DTYPE_PRNT 0x02 // Printer
#define DTYPE_PROC 0x03 // Processor
#define DTYPE_WORM 0x04 // Write-once read-multiple
#define DTYPE_CROM 0x05 // CD-ROM device
#define DTYPE_SCAN 0x06 // Scanner device
#define DTYPE_OPTI 0x07 // Optical memory device
#define DTYPE_JUKE 0x08 // Medium Changer device
#define DTYPE_COMM 0x09 // Communications device
#define DTYPE_RESL 0x0A // Reserved (low)
#define DTYPE_RESH 0x1E // Reserved (high)
#define DTYPE_UNKNOWN 0x1F // Unknown or no device type
//**********************************************************************
// %%% ANSI APPROVED VERSION DEFINITIONS %%%
//**********************************************************************
#define ANSI_MAYBE 0x0 // Device may or may not be ANSI approved stand
#define ANSI_SCSI1 0x1 // Device complies to ANSI X3.131-1986 (SCSI-1)
#define ANSI_SCSI2 0x2 // Device complies to SCSI-2
#define ANSI_RESLO 0x3 // Reserved (low)
#define ANSI_RESHI 0x7 // Reserved (high)

View file

@ -0,0 +1,229 @@
//**********************************************************************
//
// Name: WINASPI.H
//
// Description: ASPI for Windows definitions ('C' Language)
//
//**********************************************************************
#ifndef _WINASPI_H
#define _WINASPI_H
typedef BYTE *LPSRB;
#define SENSE_LEN 14 // Default sense buffer length
#define SRB_DIR_SCSI 0x00 // Direction determined by SCSI command
#define SRB_DIR_IN 0x08 // Transfer from SCSI target to host
#define SRB_DIR_OUT 0x10 // Transfer from host to SCSI targetw
#define SRB_POSTING 0x01 // Enable ASPI posting
#define SRB_EVENT_NOTIFY 0x40 // Enable ASPI command notification
#define SRB_ENABLE_RESIDUAL_COUNT 0x04 //Enable reporting of residual byte count
#define WM_ASPIPOST 0x4D42 // ASPI Post message
#define TIMEOUT 30000 // Wait 30 seconds
//**********************************************************************
// %%% ASPI Command Definitions %%%
//**********************************************************************
#define SC_HA_INQUIRY 0x00 // Host adapter inquiry
#define SC_GET_DEV_TYPE 0x01 // Get device type
#define SC_EXEC_SCSI_CMD 0x02 // Execute SCSI command
#define SC_ABORT_SRB 0x03 // Abort an SRB
#define SC_RESET_DEV 0x04 // SCSI bus device reset
//**********************************************************************
// %%% SRB Status %%%
//**********************************************************************
#define SS_PENDING 0x00 // SRB being processed
#define SS_COMP 0x01 // SRB completed without error
#define SS_ABORTED 0x02 // SRB aborted
#define SS_ABORT_FAIL 0x03 // Unable to abort SRB
#define SS_ERR 0x04 // SRB completed with error
#define SS_INVALID_CMD 0x80 // Invalid ASPI command
#define SS_INVALID_HA 0x81 // Invalid host adapter number
#define SS_NO_DEVICE 0x82 // SCSI device not installed
#define SS_INVALID_SRB 0xE0 // Invalid parameter set in SRB
#define SS_OLD_MANAGER 0xE1 // ASPI manager doesn't support Window
#define SS_ILLEGAL_MODE 0xE2 // Unsupported Windows mode
#define SS_NO_ASPI 0xE3 // No ASPI managers resident
#define SS_FAILED_INIT 0xE4 // ASPI for windows failed init
#define SS_ASPI_IS_BUSY 0xE5 // No resources available to execute cmd
#define SS_BUFFER_TO_BIG 0xE6 // Buffer size to big to handle!
//**********************************************************************
// %%% Host Adapter Status %%%
//**********************************************************************
#define HASTAT_OK 0x00 // Host adapter did not detect an error
#define HASTAT_SEL_TO 0x11 // Selection Timeout
#define HASTAT_DO_DU 0x12 // Data overrun data underrun
#define HASTAT_BUS_FREE 0x13 // Unexpected bus free
#define HASTAT_PHASE_ERR 0x14 // Target bus phase sequence failure
//**********************************************************************
// %%% SRB - HOST ADAPTER INQUIRY - SC_HA_INQUIRY %%%
//**********************************************************************
#pragma pack(push,ASPI_Structures,1)
typedef BYTE TDriveMode[64];
struct THAUnique
{
WORD BufferAlignmentMask;
BYTE AdapterUniqueFlags;
BYTE MaximumSCSITargets;
DWORD MaximumTransferLen;
BYTE Reserved[8];
};
typedef struct
{
BYTE SRB_Cmd; // ASPI command code = SC_HA_INQUIRY
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // ASPI request flags
DWORD SRB_Hdr_Rsvd; // Reserved, MUST = 0
BYTE HA_Count; // Number of host adapters present
BYTE HA_SCSI_ID; // SCSI ID of host adapter
BYTE HA_ManagerId[16]; // String describing the manager
BYTE HA_Identifier[16]; // String describing the host adapter
THAUnique HA_Unique; // Host Adapter Unique parameters
WORD HA_Rsvd1;
} SRB_HAInquiry, *PSRB_HAInquiry;
//**********************************************************************
// %%% SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE %%%
//**********************************************************************
typedef struct
{
BYTE SRB_Cmd; // ASPI command code = SC_GET_DEV_TYPE
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // Reserved
DWORD SRB_Hdr_Rsvd; // Reserved
BYTE SRB_Target; // Target's SCSI ID
BYTE SRB_Lun; // Target's LUN number
BYTE SRB_DeviceType; // Target's peripheral device type
BYTE SRB_Rsvd1; // Reserved for alignment
} SRB_GDEVBlock, *PSRB_GDEVBlock;
//**********************************************************************
// %%% SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD %%%
//**********************************************************************
typedef struct
{
BYTE SRB_Cmd; // ASPI command code = SC_EXEC_SCSI_CMD
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // ASPI request flags
DWORD SRB_Hdr_Rsvd; // Reserved
BYTE SRB_Target; // Target's SCSI ID
BYTE SRB_Lun; // Target's LUN number
WORD SRB_Rsvd1; // Reserved for Alignment
DWORD SRB_BufLen; // Data Allocation Length
BYTE *SRB_BufPointer; // Data Buffer Point
BYTE SRB_SenseLen; // Sense Allocation Length
BYTE SRB_CDBLen; // CDB Length
BYTE SRB_HaStat; // Host Adapter Status
BYTE SRB_TargStat; // Target Status
void (*SRB_PostProc)(); // Post routine
void *SRB_Rsvd2; // Reserved
BYTE SRB_Rsvd3[16]; // Reserved for expansion
BYTE CDBByte[16]; // SCSI CDB
BYTE SenseArea[SENSE_LEN+2]; // Request Sense buffer
} SRB_ExecSCSICmd, *PSRB_ExecSCSICmd;
//**********************************************************************
// %%% SRB - ABORT AN SRB - SC_ABORT_SRB %%%
//**********************************************************************
typedef struct
{
BYTE SRB_Cmd; // ASPI command code = SC_ABORT_SRB
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // ASPI request flags
DWORD SRB_Hdr_Rsvd; // Reserved, MUST = 0
LPSRB SRB_ToAbort; // Pointer to SRB to abort
} SRB_Abort;
//**********************************************************************
// %%% SRB - BUS DEVICE RESET - SC_RESET_DEV %%%
//**********************************************************************
typedef struct
{
BYTE SRB_Cmd; // ASPI command code = SC_RESET_DEV
BYTE SRB_Status; // ASPI command status byte
BYTE SRB_HaId; // ASPI host adapter number
BYTE SRB_Flags; // Reserved
DWORD SRB_Hdr_Rsvd; // Reserved
BYTE SRB_Target; // Target's SCSI ID
BYTE SRB_Lun; // Target's LUN number
BYTE SRB_Rsvd1[12]; // Reserved for Alignment
BYTE SRB_HaStat; // Host Adapter Status
BYTE SRB_TargStat; // Target Status
void *SRB_PostProc; // Post routine
void *SRB_Rsvd2; // Reserved
BYTE SRB_Rsvd3[32]; // Reserved
} SRB_BusDeviceReset, *PSRB_BusDeviceReset;
//**********************************************************************
// %%% Header for TOC Reading %%%
//**********************************************************************
struct TTrackInfo
{
BYTE Reserved1;
BYTE AdrCtrl;
BYTE TrackNummer;
BYTE Reserved2;
DWORD AbsCDAdress;
};
struct TTOCHeader
{
WORD TOCDataLength;
BYTE FirstTrack;
BYTE LastTrack;
TTrackInfo Info[100];
};
//**********************************************************************
// %%% Structure for Read Sub-Channel %%%
//**********************************************************************
struct TQChannelInfo
{
BYTE Reserved1;
BYTE AudioStatus;
WORD DataLen;
BYTE FormatCode;
BYTE ADRCtrl;
BYTE TrackNumber;
BYTE IndexNumber;
long AbsCDAdress;
long RelTrackAdress;
};
//**********************************************************************
// %%% Request Sense Data Format %%%
//**********************************************************************
typedef struct {
BYTE ErrorCode; // Error Code (70H or 71H)
BYTE SegmentNum; // Number of current segment descriptor
BYTE SenseKey; // Sense Key(See bit definitions too)
BYTE InfoByte0; // Information MSB
BYTE InfoByte1; // Information MID
BYTE InfoByte2; // Information MID
BYTE InfoByte3; // Information LSB
BYTE AddSenLen; // Additional Sense Length
BYTE ComSpecInf0; // Command Specific Information MSB
BYTE ComSpecInf1; // Command Specific Information MID
BYTE ComSpecInf2; // Command Specific Information MID
BYTE ComSpecInf3; // Command Specific Information LSB
BYTE AddSenseCode; // Additional Sense Code
BYTE AddSenQual; // Additional Sense Code Qualifier
BYTE FieldRepUCode; // Field Replaceable Unit Code
BYTE SenKeySpec15; // Sense Key Specific 15th byte
BYTE SenKeySpec16; // Sense Key Specific 16th byte
BYTE SenKeySpec17; // Sense Key Specific 17th byte
BYTE AddSenseBytes; // Additional Sense Bytes
} TSenseInfo;
#pragma pack(pop,ASPI_Structures)
#endif //_WINASPI_H