diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Input/in_cdda/windac | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Input/in_cdda/windac')
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/Aspi.h | 410 | ||||
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/Aspifunc.cpp | 378 | ||||
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/Aspifunc.h | 101 | ||||
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/Dac32.cpp | 2667 | ||||
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/Dac32.dsp | 127 | ||||
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/Dac32.h | 775 | ||||
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/Dac32.mak | 285 | ||||
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/Dac32.rc | 121 | ||||
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/NTScsi.cpp | 501 | ||||
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/NTScsi.h | 147 | ||||
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/RESOURCE.H | 17 | ||||
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/SCSIDEFS.H | 252 | ||||
-rw-r--r-- | Src/Plugins/Input/in_cdda/windac/Winaspi.h | 229 |
13 files changed, 6010 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_cdda/windac/Aspi.h b/Src/Plugins/Input/in_cdda/windac/Aspi.h new file mode 100644 index 00000000..cc55c36e --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/Aspi.h @@ -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
\ No newline at end of file diff --git a/Src/Plugins/Input/in_cdda/windac/Aspifunc.cpp b/Src/Plugins/Input/in_cdda/windac/Aspifunc.cpp new file mode 100644 index 00000000..ee8f3544 --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/Aspifunc.cpp @@ -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; +}
\ No newline at end of file diff --git a/Src/Plugins/Input/in_cdda/windac/Aspifunc.h b/Src/Plugins/Input/in_cdda/windac/Aspifunc.h new file mode 100644 index 00000000..c63c2f81 --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/Aspifunc.h @@ -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
\ No newline at end of file diff --git a/Src/Plugins/Input/in_cdda/windac/Dac32.cpp b/Src/Plugins/Input/in_cdda/windac/Dac32.cpp new file mode 100644 index 00000000..9172a1dd --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/Dac32.cpp @@ -0,0 +1,2667 @@ +// ---------------------------------------------- +// - DAC32.DLL Implementations Datei - +// - Written 1996-1998 by Christoph Schmelnik - +// ---------------------------------------------- + +// 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 +// Added function to CD Class to read Media Cataloge Number +// +// Version 1.41 : 02.05.1998 +// Changes: +// New GetInfoEx() function in CMapDrive, to allow a better result checking. +// Bugfixed error handling in CWaveSave and CDAC regarding write errors +// +// 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. + +//limit the read to 64k, because of a bug in the Adaptec drivers +#define Bug64 + +//limit the number of retries at error to 5 +#define MAXTRIES 5 +#include "dac32.h" +#include <stdlib.h> +#include <assert.h> +#include <process.h> + +#ifdef __BORLANDC__ // pgo (to make it compatible with Bormand compiler) +#define _stricmp _stricmp +#define _strlwr strlwr +#endif + +// ---------------------------------------------------------------------------------------- +// - Implementation of the private copy operators - +// - - +// - Author: Christoph Schmelnik - +// - Purpose: Check the syntax of program - +// ---------------------------------------------------------------------------------------- + +CBaseCD& CBaseCD::operator = (const CBaseCD &other) +{ + assert(!&other); + return (*this); +} + +CSCSICD& CSCSICD::operator = (const CSCSICD &other) +{ + assert(!&other); + return (*this); +} + +// ---------------------------------------------------------------------------------------- +// - Implementation of the class members of CCDAdress - +// - - +// - Author: Christoph Schmelnik - +// - Purpose: Eliminate the errors at compile time - +// ---------------------------------------------------------------------------------------- +void CCDAdress::SetRedbook(long Value) +{ + Adresse=Value >> 24; + Adresse+=((Value >> 16) & 255)*75; + Adresse+=((Value >> 8) & 255)*4500; +}; + +// ---------------------------------------------------------------------------------------- +// - Implementation of the class members of CMapInfo - +// - - +// - Author: Christoph Schmelnik - +// - Purpose: Implement the information of the TypeMappings - +// ---------------------------------------------------------------------------------------- +CMapInfo::CMapInfo() +{ + strncpy(TypNamen[0],"TOSHIBA ", 9); + strncpy(TypNamen[1],"SONY ", 9); + strncpy(TypNamen[2],"NEC ", 9); + strncpy(TypNamen[3],"HITACHI ", 9); + strncpy(TypNamen[4],"YAMAHA ", 9); + strncpy(TypNamen[5],"PIONEER ", 9); + strncpy(TypNamen[6],"IBM ", 9); + strncpy(TypNamen[7],"PLEXTOR ", 9); + strncpy(TypNamen[8],"PHILIPS ", 9); + strncpy(TypNamen[9],"GRUNDIG ", 9); + strncpy(TypNamen[10],"HP ", 9); + strncpy(TypNamen[11],"IMS ", 9); + strncpy(TypNamen[12],"MITSUMI ", 9); + strncpy(TypNamen[13],"ATAPI ", 9); + strncpy(TypNamen[14],"TOSHNEW ", 9); + strncpy(TypNamen[15],"RICOH ", 9); + strncpy(TypNamen[16],"MATSHITA", 9); + strncpy(TypNamen[17],"PLASMON ", 9); + strncpy(TypNamen[18],"KODAK ", 9); + strncpy(TypNamen[19],"TEAC ", 9); + strncpy(TypNamen[20],"CyberDrv", 9); + strncpy(TypNamen[21],"MMC-2 ", 9); // pgo + int const t[]={CDTYPE_TOSHIBA,CDTYPE_SONY,CDTYPE_NEC,CDTYPE_SONY,CDTYPE_SONY,CDTYPE_SONY, + CDTYPE_SONY,CDTYPE_PLEXTOR,CDTYPE_PHILIPS,CDTYPE_PHILIPS,CDTYPE_PHILIPS,CDTYPE_PHILIPS, + CDTYPE_PHILIPS,CDTYPE_ATAPI,CDTYPE_TOSHNEW,CDTYPE_RICOH,CDTYPE_MATSHITA,CDTYPE_PHILIPS, + CDTYPE_PHILIPS,CDTYPE_SONY,CDTYPE_CYBERDRV, + CDTYPE_CYBERDRV}; // pgo + for (int i=0; i<MaxMappings; i++) + TypMapping[i]=t[i]; +} + +char *CMapInfo::GetTypName(int Index) +{ + return TypNamen[Index]; +}; + +int CMapInfo::GetTypMapping(int Index) +{ + return TypMapping[Index]; +}; + +int CMapInfo::GetTypMappingRev(int CDType) +{ + int Index=0; + while ((Index<MaxMappings) && + (TypMapping[Index]!=CDType)) + Index++; + return Index; +}; + +// ---------------------------------------------------------------------------------------- +// - Implementation of the class members of CMapDrive - +// - - +// - Author: Christoph Schmelnik - +// - Purpose: Administration of the drive configuration - +// ---------------------------------------------------------------------------------------- +CMapDrive::CMapDrive(BOOL bDoReset) +{ + First=0; + + m_hDriveEvent=INVALID_HANDLE_VALUE; + wchar_t szEventName[32] = {0}; + wsprintf(szEventName,L"%X",this); + m_hDriveEvent=CreateEvent(NULL,TRUE,FALSE,szEventName); + if (bDoReset) + Reset(); +}; + +CMapDrive::~CMapDrive() +{ + DeleteAll(); + if (m_hDriveEvent!=INVALID_HANDLE_VALUE) + CloseHandle(m_hDriveEvent); +}; + +void CMapDrive::DeleteAll() +{ + TDriveInfoMem *Akt; + Akt=First; + while (First) + { + Akt=First; + First=Akt->Next; + delete Akt; + } +}; + +void CMapDrive::Reset() +{ + TDriveInfoMem *Akt,*Last; + DeleteAll(); + BYTE SCSIType; + TDriveInfo Info = {0}; + int DType = DTYPE_UNKNOWN; + char Revision[5] = {0}; + char ManagerID[17] = {0}; + char HAID[17] = {0}; + + THAUnique HAUnique; + MEMORYSTATUS MemStat; + MemStat.dwLength=sizeof(MEMORYSTATUS); + GlobalMemoryStatus((LPMEMORYSTATUS)&MemStat); + CMapInfo MapInfo; + int HostNum; + for (HostNum=0; HostNum<NumberOfHostAdapters; HostNum++) + { + memset(Revision,0,sizeof(Revision)); + memset(ManagerID,0,sizeof(ManagerID)); + memset(HAID,0,sizeof(HAID)); + memset(&HAUnique,0,sizeof(HAUnique)); + if (HAInquiry(HostNum,ManagerID,HAID,HAUnique)) + { + if (_stricmp(HAID, "fastcdmp") == 0) //pgo: Skip Virtual CD Adapter in Bus Scan + continue; + HostAdapterMemory[HostNum]=HAUnique.MaximumTransferLen; + for (int IDNum=0; IDNum<8; IDNum++) + for (int LUNNum=0; LUNNum<=MAXLUN; LUNNum++) + { + DType=GetDeviceInfo(HostNum,IDNum,LUNNum,SCSIType,Info.VendorID,Info.ProductID,Revision,m_hDriveEvent); + if ((DType==DTYPE_CROM)|| + (DType==DTYPE_WORM)) + { + if (SCSIType) + { + int i; + for (i=0; (i<MaxMappings) && _stricmp(Info.VendorID,MapInfo.GetTypName(i)); i++); + if (i>=MaxMappings) i=1; //pgo: avoid array out of bound + Info.Type=i; + } + else + Info.Type=MapInfo.GetTypMappingRev(CDTYPE_ATAPI); + + if (MapInfo.GetTypMapping(Info.Type)==CDTYPE_TOSHIBA) + { + char szNumbers[17] = {0}; + for (size_t i=0; i<strlen(Info.ProductID); i++) + if (isdigit(Info.ProductID[i])) + strncat(szNumbers,&Info.ProductID[i],1); + int nProductID=atoi(szNumbers); + if (((nProductID>3800) && + (nProductID<4000)) || + ((nProductID>5700) && + (nProductID<10000))) + Info.Type=MapInfo.GetTypMappingRev(CDTYPE_TOSHNEW); + } + // pgo + else if (MapInfo.GetTypMapping(Info.Type)==CDTYPE_SONY) + { + if (SCSIType) + { + char szNumbers[17] = {0}; + for (size_t i=0; i<strlen(Info.ProductID); i++) + if (isdigit(Info.ProductID[i])) + strncat(szNumbers,&Info.ProductID[i],1); + int nProductID=atoi(szNumbers); + if ((nProductID == 140) || (nProductID == 928)) + Info.Type=MapInfo.GetTypMappingRev(CDTYPE_CYBERDRV); + } + } + Info.ID=IDNum; + Info.LUN=LUNNum; + Info.HostAdapterNumber=HostNum; + Info.Mode=ModeBurst; + Info.MaxSektors=MemStat.dwTotalPhys/16/2352; + if (Info.MaxSektors>(HostAdapterMemory[HostNum]/2352)) + Info.MaxSektors=HostAdapterMemory[HostNum]/2352; +#ifdef Bug64 + if (Info.MaxSektors>27) Info.MaxSektors=27; +#else + if (Info.MaxSektors>446) Info.MaxSektors=446; +#endif + if (!Info.MaxSektors) Info.MaxSektors=26; + + Info.SynchSektors=3; + Info.Speed=0; + Info.PerformDATest=DATEST_FIRSTTRACK; + Info.SpinUpMode=SPINUP_NEVER; + Info.dwSpinUpTime=5; + Info.bUseLastReadableAddress=FALSE; + Info.bUseC2ErrorInfo=FALSE; + Info.bSpinDown=FALSE; + Akt=new TDriveInfoMem; + Akt->Info=Info; + Akt->Next=0; + if (!First) First=Akt; + else Last->Next=Akt; + //Last must be set to Akt + Last=Akt; + } + } + } + } + if (RunningNT) + { + //check all drives for direct access + int Index, Length; + wchar_t DriveList[128] = {0}, *pDrives = 0; + + Length=GetLogicalDriveStrings(128,DriveList); + if (Length) + { + pDrives=DriveList; + Index=0; + while (pDrives && *pDrives && (Index<Length)) + { + if (GetDriveType(pDrives)==DRIVE_CDROM) + { + wchar_t CDDevice[10]=L"\\\\.\\x:"; + HANDLE hDrive; + CharLower(pDrives); + //_strlwr(pDrives); + CDDevice[4]=pDrives[0]; + int IDNum=pDrives[0]-'a'; + + //For Windows NT 5 use other file flags + OSVERSIONINFO osver; + memset( &osver, 0x00, sizeof(osver) ); + osver.dwOSVersionInfoSize = sizeof(osver); + GetVersionEx( &osver ); + + DWORD dwOpenFlags = GENERIC_READ; + if ( (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osver.dwMajorVersion > 4) ) dwOpenFlags |= GENERIC_WRITE; + + hDrive=CreateFile(CDDevice,dwOpenFlags,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); + if (hDrive!=INVALID_HANDLE_VALUE) + { + //CT> added correct host/id/lun guessing + extern int getSCSIIDFromDrive(char driveletter, int *host, int *id, int *lun); + int m_lun; + getSCSIIDFromDrive((char)pDrives[0],&HostNum,&IDNum,&m_lun); + + DType=GetDeviceInfo(HostNum,IDNum,m_lun,SCSIType,Info.VendorID,Info.ProductID,Revision,hDrive); + if ((DType==DTYPE_CROM)|| + (DType==DTYPE_WORM)) + { + SCSIMaxBlocks(hDrive,&HostAdapterMemory[HostNum]); + if (SCSIType) + { + int i; + for (i=0; (i<MaxMappings) && _stricmp(Info.VendorID,MapInfo.GetTypName(i)); i++); + if (i>=MaxMappings) i=1; //pgo: avoid array out of bound + Info.Type=i; + } + else + Info.Type=MapInfo.GetTypMappingRev(CDTYPE_ATAPI); + if (MapInfo.GetTypMapping(Info.Type)==CDTYPE_TOSHIBA) + { + char szNumbers[17]; + szNumbers[0]=0; + for (size_t i=0; i<strlen(Info.ProductID); i++) + if (isdigit(Info.ProductID[i])) + strncat(szNumbers,&Info.ProductID[i],1); + int nProductID=atoi(szNumbers); + if (((nProductID>3800) && + (nProductID<4000)) || + ((nProductID>5700) && + (nProductID<10000))) + Info.Type=MapInfo.GetTypMappingRev(CDTYPE_TOSHNEW); + } + // pgo + else if (MapInfo.GetTypMapping(Info.Type)==CDTYPE_SONY) + { + if (SCSIType) + { + char szNumbers[17] = {0}; + for (size_t i=0; i<strlen(Info.ProductID); i++) + if (isdigit(Info.ProductID[i])) + strncat(szNumbers,&Info.ProductID[i],1); + int nProductID=atoi(szNumbers); + if ((nProductID == 140) || (nProductID == 928)) + Info.Type=MapInfo.GetTypMappingRev(CDTYPE_CYBERDRV); + } + } + Info.ID=IDNum; + Info.LUN=0; + Info.HostAdapterNumber=HostNum; + Info.Mode=ModeNormal; + Info.MaxSektors=MemStat.dwTotalPhys/16/2352; + if (Info.MaxSektors>(HostAdapterMemory[HostNum]/2352)) + Info.MaxSektors=HostAdapterMemory[HostNum]/2352; +#ifdef Bug64 + if (Info.MaxSektors>27) Info.MaxSektors=27; +#else + if (Info.MaxSektors>446) Info.MaxSektors=446; +#endif + if (!Info.MaxSektors || + (MapInfo.GetTypMapping(Info.Type)==CDTYPE_ATAPI)) + Info.MaxSektors=26; + Info.SynchSektors=3; + Info.Speed=0; + Info.PerformDATest=DATEST_FIRSTTRACK; + Info.SpinUpMode=SPINUP_NEVER; + Info.dwSpinUpTime=5; + Info.bUseLastReadableAddress=FALSE; + Info.bUseC2ErrorInfo=FALSE; + Info.bSpinDown=FALSE; + Akt=new TDriveInfoMem; + Akt->Info=Info; + Akt->Next=0; + if (!First) First=Akt; + else Last->Next=Akt; + //Last must be set to Akt + Last=Akt; + HostNum++; + } + CloseHandle(hDrive); + } + } + pDrives+=4; + Index+=4; + } + } + } +}; + +int CMapDrive::GetMaxDrives() +{ + int i=0; + TDriveInfoMem *Akt; + Akt=First; + while (Akt) + { + i++; + Akt=Akt->Next; + } + return i; +}; + +TDriveInfo &CMapDrive::GetInfo(int index) +{ + int i=0; + TDriveInfoMem *Akt; + Akt=First; + while ((Akt) && (i<index)) + { + i++; + Akt=Akt->Next; + } + return Akt->Info; +}; + +BOOL CMapDrive::GetInfoEx(int index, TDriveInfo *&pInfo) +{ + int i=0; + TDriveInfoMem *Akt; + Akt=First; + while ((Akt) && (i<index)) + { + i++; + Akt=Akt->Next; + } + if (!Akt) + return FALSE; + pInfo=&Akt->Info; + return TRUE; +}; + +void CMapDrive::DeleteInfo(int index) +{ + int i=0; + TDriveInfoMem *Akt,*Prev; + Akt=First; + Prev=0; + while ((Akt) && (i<index)) + { + i++; + Prev=Akt; + Akt=Akt->Next; + } + if (!Akt) return; + if (Prev) Prev->Next=Akt->Next; + else First=Akt->Next; + delete Akt; +}; + +int CMapDrive::GetMaxHostAdapters() +{ + return NumberOfHostAdapters; +}; + +int CMapDrive::GetSupportedHostAdapterMemory(int index) +{ + if ((index<NumberOfHostAdapters) && + (index>=0)) + return HostAdapterMemory[index]; + else + return -1; +}; + +void CMapDrive::SetSupportedHostAdapterMemory(int index,int Memory) +{ + if ((index<NumberOfHostAdapters) && + (index>=0)) + HostAdapterMemory[index]=Memory; +} + +int CMapDrive::GetMaxSektors(int HostAdapterNumber) +{ +#ifdef Bug64 + int Result=HostAdapterMemory[HostAdapterNumber]/2352; + if (Result>27) + Result=27; + return Result; +#else + return HostAdapterMemory[HostAdapterNumber]/2352; +#endif +}; + +// ---------------------------------------------------------------------------------------- +// - Implementation of the class members of CMapInfoJuke - +// - - +// - Author: Christoph Schmelnik - +// - Purpose: Implement the information of the TypeMappings - +// ---------------------------------------------------------------------------------------- +CMapInfoJuke::CMapInfoJuke() +{ + strncpy(TypNamen[0],"SONY ", 9); + strncpy(TypNamen[1],"PIONEER ", 9); + int const t[]={JUKETYPE_SONY,JUKETYPE_PIONEER}; + for (int i=0; i<MaxMappingsJuke; i++) + TypMapping[i]=t[i]; +} + +char *CMapInfoJuke::GetTypName(int Index) +{ + return TypNamen[Index]; +}; + +int CMapInfoJuke::GetTypMapping(int Index) +{ + return TypMapping[Index]; +}; + +int CMapInfoJuke::GetTypMappingRev(int JukeType) +{ + int Index=0; + while ((Index<MaxMappingsJuke) && + (TypMapping[Index]!=JukeType)) + Index++; + return Index; +}; + +// ---------------------------------------------------------------------------------------- +// - Implementation of the class members of CMapJuke - +// - - +// - Author: Christoph Schmelnik - +// - Purpose: Administration of the jukebox configuration - +// ---------------------------------------------------------------------------------------- +CMapJuke::CMapJuke(BOOL bDoReset) +{ + First=0; + + m_hJukeEvent=INVALID_HANDLE_VALUE; + wchar_t szEventName[32] = {0}; + wsprintf(szEventName,L"%X",this); + m_hJukeEvent=CreateEvent(NULL,TRUE,FALSE,szEventName); + if (bDoReset) + Reset(); +}; + +CMapJuke::~CMapJuke() +{ + DeleteAll(); + if (m_hJukeEvent!=INVALID_HANDLE_VALUE) + CloseHandle(m_hJukeEvent); +}; + +void CMapJuke::DeleteAll() +{ + TJukeInfoMem *Akt; + Akt=First; + while (First) + { + Akt=First; + First=Akt->Next; + if (Akt->Info.pConnectedDrives) + delete Akt->Info.pConnectedDrives; + delete Akt; + } +}; + +void CMapJuke::Reset() +{ + TJukeInfoMem *Akt,*Last; + DeleteAll(); + BYTE SCSIType = 0; + TJukeInfo Info = {0}; + int DType = DTYPE_UNKNOWN; + char Revision[5] = {0}; + char ManagerID[17] = {0}; + char HAID[17] = {0}; + + THAUnique HAUnique; + CMapInfoJuke MapInfo; + for (int HostNum=0; HostNum<NumberOfHostAdapters; HostNum++) + { + memset(Revision,0,sizeof(Revision)); + memset(ManagerID,0,sizeof(ManagerID)); + memset(HAID,0,sizeof(HAID)); + memset(&HAUnique,0,sizeof(HAUnique)); + if (HAInquiry(HostNum,ManagerID,HAID,HAUnique)) + { + for (int IDNum=0; IDNum<8; IDNum++) + { + for (int LUNNum=0; LUNNum<=MAXLUN; LUNNum++) + { + memset(&Info,0,sizeof(Info)); + DType=GetDeviceInfo(HostNum,IDNum,LUNNum,SCSIType,Info.VendorID,Info.ProductID,Revision,m_hJukeEvent); + if (DType==DTYPE_JUKE) + { + int i; + for (i=0; (i<MaxMappingsJuke) && _stricmp(Info.VendorID,MapInfo.GetTypName(i)); i++); + if (_stricmp(Info.VendorID,MapInfo.GetTypName(i))) i=JUKETYPE_SONY; + Info.Type=i; + switch (Info.Type) + { + case JUKETYPE_PIONEER : + Info.MaxDrives=4; //currently only data for the 500x changer implemeneted + Info.MaxDiscs=500; + break; + case JUKETYPE_SONY : + default: + Info.MaxDrives=2; + Info.MaxDiscs=100; + break; + } + Info.pConnectedDrives=new int[Info.MaxDrives]; + for (int nDriveNum=0; nDriveNum<Info.MaxDrives; nDriveNum++) + Info.pConnectedDrives[nDriveNum]=-1; + Info.ID=IDNum; + Info.LUN=LUNNum; + Info.HostAdapterNumber=HostNum; + + Akt=new TJukeInfoMem; + Akt->Info=Info; + Akt->bIsWorking=FALSE; + Akt->Next=0; + if (!First) First=Akt; + else Last->Next=Akt; + //Last must be set to Akt + Last=Akt; + } + } + } + } + } +}; + +int CMapJuke::GetMaxJukes() +{ + int i=0; + TJukeInfoMem *Akt; + Akt=First; + while (Akt) + { + i++; + Akt=Akt->Next; + } + return i; +}; + +TJukeInfo &CMapJuke::GetInfo(int index) +{ + int i=0; + TJukeInfoMem *Akt; + Akt=First; + while ((Akt) && (i<index)) + { + i++; + Akt=Akt->Next; + } + return Akt->Info; +}; + +BOOL CMapJuke::IsWorking(int index) +{ + int i=0; + TJukeInfoMem *Akt; + Akt=First; + while ((Akt) && (i<index)) + { + i++; + Akt=Akt->Next; + } + return Akt->bIsWorking; +}; + +void CMapJuke::SetWorking(int index,BOOL bIsWorking) +{ + int i=0; + TJukeInfoMem *Akt; + Akt=First; + while ((Akt) && (i<index)) + { + i++; + Akt=Akt->Next; + } + Akt->bIsWorking=bIsWorking; +}; + +void CMapJuke::DeleteInfo(int index) +{ + int i=0; + TJukeInfoMem *Akt,*Prev; + Akt=First; + Prev=0; + while ((Akt) && (i<index)) + { + i++; + Prev=Akt; + Akt=Akt->Next; + } + if (!Akt) return; + if (Prev) Prev->Next=Akt->Next; + else First=Akt->Next; + if (Akt->Info.pConnectedDrives) + delete Akt->Info.pConnectedDrives; + delete Akt; +}; + +// ---------------------------------------------------------------------------------------- +// - Implementation of the class members of CJukeBox - +// - - +// - Author: Christoph Schmelnik - +// - Purpose: Control the basic JukeBox functions over ASPI - +// ---------------------------------------------------------------------------------------- +CJukeBox::CJukeBox (TJukeInfo &xInfo):Config(xInfo) +{ + m_hJukeEvent=INVALID_HANDLE_VALUE; + wchar_t szEventName[32] = {0}; + wsprintf(szEventName,L"%X",this); + m_hJukeEvent=CreateEvent(NULL,TRUE,FALSE,szEventName); + assert(m_hJukeEvent); +} + +CJukeBox::~CJukeBox() +{ + if (m_hJukeEvent!=INVALID_HANDLE_VALUE) + CloseHandle(m_hJukeEvent); +} + +BOOL CJukeBox::MoveMedium(int Source,int Destination) +{ + switch (MapInfo.GetTypMapping(Config.Type)) + { + case JUKETYPE_PIONEER : + if ((Source<1) || (Source>Config.MaxDiscs)) + if ((Source<0x4000) || (Source>=(0x4000+Config.MaxDrives))) + return FALSE; + if ((Destination<1) || (Destination>Config.MaxDiscs)) + if ((Destination<0x4000) || (Destination>=(0x4000+Config.MaxDrives))) + return FALSE; + break; + case JUKETYPE_SONY : + default: + if ((Source<1) || (Source>Config.MaxDiscs)) + { + if ((Source<0x4000) || (Source>=(0x4000+Config.MaxDrives))) + return FALSE; + else + Source-=0x3fff; + } + else + Source+=10; + if ((Destination<1) || (Destination>Config.MaxDiscs)) + { + if ((Destination<0x4000) || (Destination>=(0x4000+Config.MaxDrives))) + return FALSE; + else + Destination-=0x3fff; + } + else + Destination+=10; + break; + } + + while (!TestUnitReady(Config.HostAdapterNumber,Config.ID,Config.LUN,m_hJukeEvent)); + TOpcode OpC; + OpC[0]=0xa5; + OpC[1]=Config.LUN>>5; + OpC[2]=0x00; + OpC[3]=0x00; + OpC[4]=Source/256; + OpC[5]=Source%256; + OpC[6]=Destination/256; + OpC[7]=Destination%256; + OpC[8]=0x00; + OpC[9]=0x00; + OpC[10]=0x00; + OpC[11]=0x00; + return ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,12,NULL,0,m_hJukeEvent); +} + +// ---------------------------------------------------------------------------------------- +// - Implementation of the class members of CBaseCD - +// - - +// - Author: Christoph Schmelnik - +// - Purpose: The drive independent functions to access the CD-ROM drives - +// ---------------------------------------------------------------------------------------- +int CBaseCD::Lasterror() +{ + int h; + h=Error; + Error=CDOK; + return h; +} + +int CBaseCD::ReadFirstTrackInfo(TTrackList &Infos) +{ + if (!FirstTrack) return 0; + AktTrack=FirstTrack; + Infos=AktTrack->Info; + return 1; +} + +int CBaseCD::ReadNextTrackInfo(TTrackList &Infos) +{ + if ((!FirstTrack) || + (!AktTrack->Next)) return 0; + AktTrack=AktTrack->Next; + Infos=AktTrack->Info; + return 1; +} + +int CBaseCD::ReadPrevTrackInfo(TTrackList &Infos) +{ + if ((!FirstTrack) || + (!AktTrack->Prev)) return 0; + AktTrack=AktTrack->Prev; + Infos=AktTrack->Info; + return 1; +} + +int CBaseCD::ReadTrackInfo(TTrackList &Infos) +{ + if ((!FirstTrack) || + (Infos.TrackNummer<1)) return 0; + if (!AktTrack) + AktTrack=FirstTrack; + if (AktTrack->Info.TrackNummer==Infos.TrackNummer) + { + Infos=AktTrack->Info; + return 1; + } + while ((AktTrack->Info.TrackNummer>Infos.TrackNummer) && + (AktTrack->Prev)) + AktTrack=AktTrack->Prev; + while ((AktTrack->Info.TrackNummer<Infos.TrackNummer) && + (AktTrack->Next)) + AktTrack=AktTrack->Next; + if (AktTrack->Info.TrackNummer!=Infos.TrackNummer) return 0; + Infos=AktTrack->Info; + return 1; +} + +int CBaseCD::ReadMaxTracks() +{ + TTrackListeMem *Laeufer; + if (!FirstTrack) return 0; + Laeufer=AktTrack; + while (Laeufer->Next) + Laeufer=Laeufer->Next; + return Laeufer->Info.TrackNummer; +} + +void CBaseCD::DeleteTrackList() +{ + while (FirstTrack) + { + AktTrack=FirstTrack->Next; + delete FirstTrack; + FirstTrack=AktTrack; + } +} + + +// ---------------------------------------------------------------------------------------- +// - Implementation of the class members of CSCSICD - +// - - +// - Author: Christoph Schmelnik - +// - Purpose: Control the basic CDROM functions over ASPI - +// ---------------------------------------------------------------------------------------- +CSCSICD::CSCSICD (char drive, TDriveInfo &xInfo):Config(xInfo) +{ + m_bSpeedTableInitialized=FALSE; + FirstTrack=0; + NECRotationSpeed = 0; // pgo + Changed=FALSE; + CDPresentLast=TRUE; + Error=CDOK; + m_hDriveEvent=INVALID_HANDLE_VALUE; + memset(&m_SenseInfo,0,sizeof(TSenseInfo)); + if ((Config.HostAdapterNumber>=NumberOfHostAdapters) && + RunningNT) + { + DWORD dwFlags; + OSVERSIONINFO osver; + wchar_t CDDevice[10]=L"\\\\.\\x:"; + CDDevice[4]=(wchar_t)drive;//(Config.HostAdapterNumber + 'A'/* + 1*/); + //For Windows NT 5 use other file flags + 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; + + m_hDriveEvent = CreateFile( CDDevice, dwFlags, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + } + else + { + wchar_t szEventName[32] = {0}; + wsprintf(szEventName,L"%X",this); + m_hDriveEvent=CreateEvent(NULL,TRUE,FALSE,szEventName); + assert(m_hDriveEvent); + } + TDriveStatus DInfo=Get_DriveStatus(); + if (DInfo.CDPresent) ReRead(); +} + +CSCSICD::~CSCSICD() +{ + DeleteTrackList(); + if (m_hDriveEvent!=INVALID_HANDLE_VALUE) + CloseHandle(m_hDriveEvent); +} + +void CSCSICD::PrepareCDDA() +{ + switch (MapInfo.GetTypMapping(Config.Type)) + { + case CDTYPE_TOSHIBA : + { + memset(&ModeData,0,sizeof(ModeData)); + if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,0,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + ModeData[0]=0; + TDriveMode ModeSelectData; + ModeSelectData[0]=0x00; + ModeSelectData[1]=0x00; + ModeSelectData[2]=0x00; + ModeSelectData[3]=0x08; + ModeSelectData[4]=0x82; + ModeSelectData[5]=0x00; + ModeSelectData[6]=0x00; + ModeSelectData[7]=0x00; + ModeSelectData[8]=0x00; + ModeSelectData[9]=0x00; + ModeSelectData[10]=0x09; + ModeSelectData[11]=0x30; + if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSelectData,12,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + break; + } + case CDTYPE_TOSHNEW : + { + memset(&ModeData,0,sizeof(ModeData)); + if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,15,0x20,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + ModeData[0]=0; + TDriveMode ModeSelectData; + ModeSelectData[0]=0x00; + ModeSelectData[1]=0x00; + ModeSelectData[2]=0x00; + ModeSelectData[3]=0x08; + ModeSelectData[4]=0x82; + ModeSelectData[5]=0x00; + ModeSelectData[6]=0x00; + ModeSelectData[7]=0x00; + ModeSelectData[8]=0x00; + ModeSelectData[9]=0x00; + ModeSelectData[10]=0x09; + ModeSelectData[11]=0x30; + + ModeSelectData[12]=0x20; + ModeSelectData[13]=0x01; + ModeSelectData[14]=(ModeData[14] & 0xcf)|0x10; + if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSelectData,15,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + break; + } + case CDTYPE_NEC : + { + memset(&ModeData,0,sizeof(ModeData)); + if (!addModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + NECRotationSpeed=ModeData[6] & 0x20; + ModeData[6]=ModeData[6]|0x20; + if (!addModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + break; + } + case CDTYPE_PHILIPS : + case CDTYPE_MATSHITA : + { + memset(&ModeData,0,sizeof(ModeData)); + if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,0,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + ModeData[0]=0; + TDriveMode ModeSelectData; + ModeSelectData[0]=0x00; + ModeSelectData[1]=0x00; + ModeSelectData[2]=0x00; + ModeSelectData[3]=0x08; + ModeSelectData[4]=0x00; + ModeSelectData[5]=0x00; + ModeSelectData[6]=0x00; + ModeSelectData[7]=0x00; + ModeSelectData[8]=0x00; + ModeSelectData[9]=0x00; + ModeSelectData[10]=0x09; + ModeSelectData[11]=0x30; + if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSelectData,12,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + break; + } + } +} + +void CSCSICD::ReadCDDA(CCDAdress StartSektor,long Sektoranzahl,void *Buffer,BOOL bUseC2ErrorInfo) +{ + TOpcode OpC; + OpC[1]=0x00; + OpC[2]=0x00; + OpC[3]=LOBYTE(HIWORD(StartSektor.GetHSG())); + OpC[4]=HIBYTE(LOWORD(StartSektor.GetHSG())); + OpC[5]=LOBYTE(LOWORD(StartSektor.GetHSG())); + OpC[6]=0x00; + switch (MapInfo.GetTypMapping(Config.Type)) + { + case CDTYPE_TOSHIBA : + case CDTYPE_TOSHNEW : + { + OpC[0]=0x28; + OpC[7]=HIBYTE(LOWORD(Sektoranzahl)); + OpC[8]=LOBYTE(LOWORD(Sektoranzahl)); + OpC[9]=0x00; + FillSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,Buffer,Sektoranzahl*2352,ReadSRB,m_hDriveEvent); + break; + } + case CDTYPE_SONY : + case CDTYPE_RICOH : + case CDTYPE_PLEXTOR : + { + OpC[0]=0xD8; + OpC[7]=0x00; + OpC[8]=HIBYTE(LOWORD(Sektoranzahl)); + OpC[9]=LOBYTE(LOWORD(Sektoranzahl)); + // benski + if (bUseC2ErrorInfo) + OpC[10]=0x04; + else + OpC[10]=0x00; + OpC[11]=0x00; + FillSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,12,Buffer,(bUseC2ErrorInfo)?(Sektoranzahl*2646):(Sektoranzahl*2352),ReadSRB,m_hDriveEvent); + break; + } + case CDTYPE_NEC : + { + OpC[0]=0xD4; + OpC[7]=HIBYTE(LOWORD(Sektoranzahl)); + OpC[8]=LOBYTE(LOWORD(Sektoranzahl)); + OpC[9]=0x00; + FillSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,Buffer,Sektoranzahl*2352,ReadSRB,m_hDriveEvent); + break; + } + case CDTYPE_MATSHITA : + { + OpC[0]=0xD4; + OpC[7]=0x00; + OpC[8]=HIBYTE(LOWORD(Sektoranzahl)); + OpC[9]=LOBYTE(LOWORD(Sektoranzahl)); + OpC[10]=0x00; + OpC[11]=0x00; + FillSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,12,Buffer,Sektoranzahl*2352,ReadSRB,m_hDriveEvent); + break; + } + case CDTYPE_PHILIPS : + { + OpC[0]=0x28; + OpC[7]=HIBYTE(LOWORD(Sektoranzahl)); + OpC[8]=LOBYTE(LOWORD(Sektoranzahl)); + OpC[9]=0x00; + FillSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,Buffer,Sektoranzahl*2352,ReadSRB,m_hDriveEvent); + break; + } + case CDTYPE_ATAPI : + case CDTYPE_CYBERDRV : + { + OpC[0]=0xBE; + OpC[1]=0x04; + OpC[7]=HIBYTE(LOWORD(Sektoranzahl)); + OpC[8]=LOBYTE(LOWORD(Sektoranzahl)); + OpC[9]=0xF0; + // benski + if (bUseC2ErrorInfo) + OpC[9]|=2; // flag 2 is supposed to mean check for C2 error info + OpC[10]=0x00; + OpC[11]=0x00; + // with C2 error info, our sector size is now 2646 bytes + FillSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,12,Buffer,bUseC2ErrorInfo?(Sektoranzahl*2646):(Sektoranzahl*2352),ReadSRB,m_hDriveEvent); + break; + } + } + ExecuteSCSIRequest(ReadSRB,m_hDriveEvent); + StartReadTime=GetTickCount(); +} + +BOOL CSCSICD::WaitCDDA(BOOL bImmediate) +{ + BYTE Status=WaitSCSIRequest(ReadSRB,m_hDriveEvent,bImmediate); + if ((Status!=SS_PENDING) && + (Status!=SS_COMP)) + { + memcpy(&m_SenseInfo,&ReadSRB.SenseArea,SENSE_LEN); + Error=CDASPIError; + } + if ((Status==SS_PENDING) && + !bImmediate) + { + DWORD AktReadTime=GetTickCount(); + if (abs((long long)AktReadTime-StartReadTime)>12000) + { + AbortSCSIRequest(ReadSRB); + Error=CDTimeOut; + Status=SS_COMP; + } + } + return (Status!=SS_PENDING); +} + +void CSCSICD::FinishCDDA() +{ + switch (MapInfo.GetTypMapping(Config.Type)) + { + case CDTYPE_TOSHIBA : + { + if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + break; + } + case CDTYPE_TOSHNEW : + { + if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,15,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + break; + } + case CDTYPE_NEC : + { + ModeData[6]=ModeData[6]|NECRotationSpeed; + if (!addModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + break; + } + case CDTYPE_PHILIPS : + case CDTYPE_MATSHITA : + { + if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeData,12,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + break; + } + } +} + +void CSCSICD::SortWaveData(DWORD *Data,int Samples) +{ + switch (MapInfo.GetTypMapping(Config.Type)) + { + case CDTYPE_PHILIPS : +// RICOH Drives doesn't seem to swap the bytes +// This has been evaluated with the CD-RW drives +// So they are even just handled like SONY drives, but i don't remove this type +// case CDTYPE_RICOH : + { + for (int i=0; i<Samples; i++) + Data[i]=((Data[i]&0xff00ff00)>>8)| + ((Data[i]&0x00ff00ff)<<8); + break; + } + } +} + +CCDAdress CSCSICD::GetErrorAdress() +{ + CCDAdress h; + h.SetHSG(0); + if ((Error!=CDOK)&& + (ReadSRB.SRB_TargStat==STATUS_CHKCOND)) + h.SetHSG((ReadSRB.SenseArea[3]<<24)+ + (ReadSRB.SenseArea[4]<<16)+ + (ReadSRB.SenseArea[5]<<8)+ + ReadSRB.SenseArea[6]); + return h; +} + +void CSCSICD::Play_Audio(CCDAdress StartSektor,long Sektoranzahl) +{ + while (!TestUnitReady(Config.HostAdapterNumber,Config.ID,Config.LUN,m_hDriveEvent)); + TOpcode OpC; + OpC[0]=0x45; + OpC[1]=0x00; + OpC[2]=HIBYTE(HIWORD(StartSektor.GetHSG())); + OpC[3]=LOBYTE(HIWORD(StartSektor.GetHSG())); + OpC[4]=HIBYTE(LOWORD(StartSektor.GetHSG())); + OpC[5]=LOBYTE(LOWORD(StartSektor.GetHSG())); + OpC[6]=0x00; + OpC[7]=HIBYTE(LOWORD(Sektoranzahl)); + OpC[8]=LOBYTE(LOWORD(Sektoranzahl)); + OpC[9]=0x00; + if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,10,NULL,0,m_hDriveEvent)) + Error=CDDriveNotReady; +} + +void CSCSICD::Stop_Audio() +{ + while (!TestUnitReady(Config.HostAdapterNumber,Config.ID,Config.LUN,m_hDriveEvent)); + TOpcode OpC; +/* OpC[0]=0x1b; + OpC[1]=0x00; + OpC[2]=0x00; + OpC[3]=0x00; + OpC[4]=0x00; + OpC[5]=0x00; +*/ + OpC[0]=0x2b; + OpC[1]=0x00; + OpC[2]=0x00; + OpC[3]=0x00; + OpC[4]=0x00; + OpC[5]=0x00; + OpC[6]=0x00; + OpC[7]=0x00; + OpC[8]=0x00; + OpC[9]=0x00; + if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,10,NULL,0,m_hDriveEvent)) + Error=CDDriveNotReady; +} + +void CSCSICD::Pause_Audio() +{ + while (!TestUnitReady(Config.HostAdapterNumber,Config.ID,Config.LUN,m_hDriveEvent)); + TOpcode OpC; + OpC[0]=0x4b; + OpC[1]=0x00; + OpC[2]=0x00; + OpC[3]=0x00; + OpC[4]=0x00; + OpC[5]=0x00; + OpC[6]=0x00; + OpC[7]=0x00; + OpC[8]=0x00; + OpC[9]=0x00; + if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,10,NULL,0,m_hDriveEvent)) + Error=CDDriveNotReady; +} + +void CSCSICD::Resume_Audio() +{ + while (!TestUnitReady(Config.HostAdapterNumber,Config.ID,Config.LUN,m_hDriveEvent)); + TOpcode OpC; + OpC[0]=0x4b; + OpC[1]=0x00; + OpC[2]=0x00; + OpC[3]=0x00; + OpC[4]=0x00; + OpC[5]=0x00; + OpC[6]=0x00; + OpC[7]=0x00; + OpC[8]=0x01; + OpC[9]=0x00; + if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,10,NULL,0,m_hDriveEvent)) + Error=CDDriveNotReady; +} + +TDriveStatus CSCSICD::Get_DriveStatus() +{ + TDriveStatus h = {0}; +/* TOpcode OpC; + TQChannelInfo ChannelInfo; + BOOL b; + memset(&ChannelInfo,0,sizeof(ChannelInfo)); + OpC[0]=0x42; + OpC[1]=0x02; + OpC[2]=0x40; + OpC[3]=0x01; + OpC[4]=0x00; + OpC[5]=0x00; + OpC[6]=0x00; + OpC[7]=0x00; + OpC[8]=sizeof(ChannelInfo); + OpC[9]=0x00; + if (MapInfo.GetTypMapping(Config.Type)==CDTYPE_ATAPI) + { + OpC[10]=0; + OpC[11]=0; + b=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,12,(void *)&ChannelInfo,sizeof(ChannelInfo),m_hDriveEvent); + } + else + b=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,10,(void *)&ChannelInfo,sizeof(ChannelInfo),m_hDriveEvent); + if (b && ChannelInfo.DataLen) +*/ + if (TestUnitReady(Config.HostAdapterNumber,Config.ID,Config.LUN,m_hDriveEvent)) + h.CDPresent=TRUE; + else + h.CDPresent=FALSE; + if (h.CDPresent!=CDPresentLast) Changed=TRUE; + CDPresentLast=h.CDPresent; + return h; +} + +BOOL CSCSICD::MediaChanged() +{ + BOOL h; + h=Changed; + //if (CDPresentLast) + Changed=FALSE; + return h; +} + +TAudioStatus CSCSICD::Get_AudioStatus_Info() +{ + TAudioStatus h; + TOpcode OpC; + TQChannelInfo ChannelInfo; + BOOL b; + memset(&ChannelInfo,0,sizeof(ChannelInfo)); + OpC[0]=0x42; + OpC[1]=0x02; + OpC[2]=0x40; + OpC[3]=0x01; + OpC[4]=0x00; + OpC[5]=0x00; + OpC[6]=0x00; + OpC[7]=0x00; + OpC[8]=0x10; + OpC[9]=0x00; + h.Pause=FALSE; + h.IsPlaying=FALSE; + h.IsDone=FALSE; + h.PlayError=FALSE; + if (MapInfo.GetTypMapping(Config.Type)==CDTYPE_ATAPI) + { + OpC[10]=0; + OpC[11]=0; + b=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,12,(void *)&ChannelInfo,16,m_hDriveEvent); + } + else + b=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,(void *)&ChannelInfo,16,m_hDriveEvent); + if (b && ChannelInfo.DataLen) + { +// if (!CDPresentLast) Changed=TRUE; +// CDPresentLast=TRUE; + switch (ChannelInfo.AudioStatus) + { + case 0x11 : h.IsPlaying=TRUE; break; + case 0x12 : h.Pause=TRUE; break; + case 0x13 : h.IsDone=TRUE; break; + case 0x14 : h.PlayError=TRUE; break; + } + h.AbsSektor.SetRedbook(ChannelInfo.AbsCDAdress); + h.RelSektor.SetRedbook(ChannelInfo.RelTrackAdress); + h.TrackNummer=ChannelInfo.TrackNumber; + } + else + { +// if (CDPresentLast) Changed=TRUE; +// CDPresentLast=FALSE; + h.PlayError=TRUE; + Error=CDNoCD; + } + return h; +} + +void CSCSICD::Get_MediaCatalogNumber(char szUPC[16]) +{ + TOpcode OpC; + BYTE Info[24] = {0}; + BOOL b; + szUPC[0]=0; + OpC[0]=0x42; + OpC[1]=0x02; + OpC[2]=0x40; + OpC[3]=0x02; + OpC[4]=0x00; + OpC[5]=0x00; + OpC[6]=0x00; + OpC[7]=0x00; + OpC[8]=sizeof(Info); + OpC[9]=0x00; + if (MapInfo.GetTypMapping(Config.Type)==CDTYPE_ATAPI) + { + OpC[10]=0; + OpC[11]=0; + b=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,12,(void *)&Info,sizeof(Info),m_hDriveEvent); + } + else + b=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,(void *)&Info,sizeof(Info),m_hDriveEvent); + if (b && (Info[8]&0x80)) + { + BOOL bIsEmpty=TRUE; + for (int i=0; i<15; i++) + { + BYTE Value=Info[i+9]; + if (Value) + bIsEmpty=FALSE; + if (Value<10) + Value+=0x30; + szUPC[i]=Value; + } + szUPC[15]=0; + if (bIsEmpty) + szUPC[0]=0; + } +} + +void CSCSICD::EjectDisk() +{ + TOpcode OpC; + OpC[0]=0x1b; + OpC[1]=0x00; + OpC[2]=0x00; + OpC[3]=0x00; + OpC[4]=0x02; + OpC[5]=0x00; + if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,6,NULL,0,m_hDriveEvent)) + Error=CDDriveNotReady; +} + +void CSCSICD::LockDoor(int Lock) +{ + TOpcode OpC; + OpC[0]=0x1e; + OpC[1]=0x00; + OpC[2]=0x00; + OpC[3]=0x00; + OpC[4]=((BYTE) Lock) & 1; + OpC[5]=0x00; + if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,6,NULL,0,m_hDriveEvent)) + Error=CDDriveNotReady; +} + +void CSCSICD::CloseTray() +{ + TOpcode OpC; + OpC[0]=0x1b; + OpC[1]=0x00; + OpC[2]=0x00; + OpC[3]=0x00; + OpC[4]=0x03; + OpC[5]=0x00; + if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,0,OpC,6,NULL,0,m_hDriveEvent)) + Error=CDDriveNotReady; +} + +int Swap(int value) +{ + int result=(value & 0xff000000)>>24; + result|=(value & 0x00ff0000)>>8; + result|=(value & 0x0000ff00)<<8; + result|=(value & 0x000000ff)<<24; + return result; +} + +void CSCSICD::ReRead() +{ + DeleteTrackList(); + m_bSpeedTableInitialized=FALSE; + TTOCHeader TOCHeader; + memset(&TOCHeader,0,sizeof(TOCHeader)); + TOpcode OpC; + OpC[0]=0x43; + OpC[1]=0; + OpC[2]=0; + OpC[3]=0; + OpC[4]=0; + OpC[5]=0; + OpC[6]=0; + OpC[7]=HIBYTE(sizeof(TTOCHeader)); + OpC[8]=LOBYTE(sizeof(TTOCHeader)); + OpC[9]=0; + + BOOL r=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,(void*)&TOCHeader,sizeof(TOCHeader),m_hDriveEvent); + if (r && TOCHeader.FirstTrack && TOCHeader.LastTrack) + { + TTrackListeMem *Last; + CCDAdress Ende; + Last=FirstTrack; + for (int i=TOCHeader.FirstTrack; i<=TOCHeader.LastTrack; i++) + { + AktTrack=new TTrackListeMem; + //AbsCDAdress + //AdrCtrl + AktTrack->Info.TrackNummer=TOCHeader.Info[i-1].TrackNummer; + AktTrack->Info.StartSektor.SetHSG(Swap(TOCHeader.Info[i-1].AbsCDAdress)+150); + Ende.SetHSG(Swap(TOCHeader.Info[i].AbsCDAdress)+150); + AktTrack->Info.Laenge=Ende.GetHSG()-AktTrack->Info.StartSektor.GetHSG(); + AktTrack->Info.StartSektor.SetHSG(AktTrack->Info.StartSektor.GetHSG()-150); + if (TOCHeader.Info[i-1].AdrCtrl & 8) + AktTrack->Info.Flags.AudioChannels=4; + else + AktTrack->Info.Flags.AudioChannels=2; + AktTrack->Info.Flags.PreEmphasis=(TOCHeader.Info[i-1].AdrCtrl & 1); + AktTrack->Info.Flags.DataTrack=(TOCHeader.Info[i-1].AdrCtrl & 4); + AktTrack->Info.Flags.CopyProhibeted=!(TOCHeader.Info[i-1].AdrCtrl & 2); + AktTrack->Prev=Last; + AktTrack->Next=0; + if (FirstTrack) + Last->Next=AktTrack; + else + FirstTrack=AktTrack; + Last=AktTrack; + } + // check for CD-Extra + if (AktTrack) + { + if (AktTrack->Info.Flags.DataTrack) + { + Last=AktTrack->Prev; + if (Last && !Last->Info.Flags.DataTrack) + { + if (Last->Info.Laenge>11400) + Last->Info.Laenge-=11400; + } + } + } + } + else + { + if (CDPresentLast) Changed=TRUE; + CDPresentLast=FALSE; + Error=CDDriveNotReady; + } +} + +CCDAdress CSCSICD::GetLastReadableAddress(CCDAdress StartSektor) +{ + CCDAdress LastSektor; + BYTE RetVal[8] = {0}; + TOpcode OpC; + OpC[0]=0x25; + OpC[1]=0; + OpC[2]=HIBYTE(HIWORD(StartSektor.GetHSG())); + OpC[3]=LOBYTE(HIWORD(StartSektor.GetHSG())); + OpC[4]=HIBYTE(LOWORD(StartSektor.GetHSG())); + OpC[5]=LOBYTE(LOWORD(StartSektor.GetHSG())); + OpC[6]=0; + OpC[7]=0; + OpC[8]=1; //Set PMI Bit + OpC[9]=0; + + BOOL r=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,10,(void*)&RetVal,sizeof(RetVal),m_hDriveEvent); + if (!r) + return StartSektor; + LastSektor.SetHSG((RetVal[0]<<24)+(RetVal[1]<<16)+(RetVal[2]<<8)+RetVal[3]); + return LastSektor; +} + +int CSCSICD::GetMaxSektors() +{ + return Config.MaxSektors; +}; + +int CSCSICD::GetSynchSektors() +{ + return Config.SynchSektors; +}; + +int CSCSICD::GetMode() +{ + return Config.Mode; +}; + +int CSCSICD::GetSpeed() +{ + return Config.Speed; +}; + +TSenseInfo CSCSICD::GetSense() +{ + TSenseInfo SenseInfo; + memset(&SenseInfo,0,sizeof(SenseInfo)); + TOpcode OpC; + OpC[0]=0x03; + OpC[1]=0; + OpC[2]=0; + OpC[3]=0; + OpC[4]=sizeof(SenseInfo); + OpC[5]=0; + + BOOL r=ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_IN,OpC,6,(void*)&SenseInfo,sizeof(SenseInfo),m_hDriveEvent); + if (!r) + memset(&SenseInfo,0,sizeof(SenseInfo)); + return SenseInfo; +} + +TSenseInfo CSCSICD::GetLastSenseInfo() +{ + TSenseInfo Info=m_SenseInfo; + memset(&m_SenseInfo,0,sizeof(TSenseInfo)); + return Info; +} + +void CSCSICD::InitSpeedTable() +{ + if (m_bSpeedTableInitialized) + return; + SupportedSpeeds=0; + switch (MapInfo.GetTypMapping(Config.Type)) + { + case CDTYPE_TOSHIBA : + break; + case CDTYPE_TOSHNEW : + { + SpeedTable[0]=2352*75; + SpeedTable[1]=2352*75*4; + SpeedTable[2]=2352*75*4; + SpeedTable[3]=-2; + SupportedSpeeds=4; + break; + } + case CDTYPE_SONY : + case CDTYPE_RICOH : + case CDTYPE_ATAPI : + case CDTYPE_CYBERDRV : + { + int LastSpeed=GetCurrentSpeed(); + int Speed=65532000; + BOOL bFound=FALSE; + while (!bFound && (Speed>0)) + { + SetCurrentSpeed(Speed); + if (Lasterror()==CDOK) + { + int ResultingSpeed=GetCurrentSpeed(); + if (Lasterror()==CDOK) + { + bFound=FALSE; + for (int i=0; i<SupportedSpeeds; i++) + { + if (SpeedTable[i]==ResultingSpeed) + bFound=TRUE; + } + if (!bFound) + { + SpeedTable[SupportedSpeeds]=ResultingSpeed; + SupportedSpeeds++; + Speed=ResultingSpeed-2352*75; + } + else + { + Speed-=(2352*75); + bFound=FALSE; + } + } + } + else + Speed=0; + } + if (SupportedSpeeds>1) + { + //Swap entries + for (int i=0; i<(SupportedSpeeds/2); i++) + { + int Help=SpeedTable[i]; + SpeedTable[i]=SpeedTable[SupportedSpeeds-1-i]; + SpeedTable[SupportedSpeeds-1-i]=Help; + } + } + SetCurrentSpeed(LastSpeed); + break; + } + case CDTYPE_PLEXTOR : + { + int LastSpeed=GetCurrentSpeed(); + for (int index=1; index<=20; index++) + { + SetCurrentSpeed(index*2352*75); + if (Lasterror()==CDOK) + { + int Speed=GetCurrentSpeed(); + if (Lasterror()==CDOK) + { + BOOL found=FALSE; + for (int i=0; i<SupportedSpeeds; i++) + { + if (SpeedTable[i]==Speed) + found=TRUE; + } + if (!found) + { + SpeedTable[SupportedSpeeds]=Speed; + SupportedSpeeds++; + } + } + } + } + SetCurrentSpeed(LastSpeed); + break; + } + case CDTYPE_NEC : + { + break; + } + case CDTYPE_PHILIPS : + case CDTYPE_MATSHITA : + { + int LastSpeed=GetCurrentSpeed(); + SpeedTable[0]=-1; + SupportedSpeeds++; + for (int index=1; index<8; index++) + { + SetCurrentSpeed(2352*75*index); + if (Lasterror()==CDOK) + { + int Speed=GetCurrentSpeed(); + if ((Lasterror()==CDOK) && + (Speed==2352*75*index)) + { + SpeedTable[SupportedSpeeds]=2352*75*index; + SupportedSpeeds++; + } + } + } + SetCurrentSpeed(LastSpeed); + break; + } + } + m_bSpeedTableInitialized=TRUE; +} + +BYTE CSCSICD::GetSupportedSpeeds() +{ + return SupportedSpeeds; +} + +BOOL IsOldPhilips(TDriveInfo *pConfig) +{ + BOOL bResult=FALSE; + if (strstr(pConfig->ProductID,"2000")) + bResult=TRUE; + if (strstr(pConfig->ProductID,"4020")) + bResult=TRUE; + return bResult; +} + +//return the identifictaion number for the plextor models +//defined values: +#define PX4X 0 +#define PX6X 1 +#define PX8X 2 +#define PX12X 3 +#define PX20X 4 +#define PX32X 5 +#define PXR412 6 +#define PX40X 7 + +DWORD GetPlextorModel(TDriveInfo *pConfig) +{ + DWORD dwResult=PX40X; + char szId[7] = {0}; + strncpy(szId,&pConfig->ProductID[10],6); + szId[6]=0; + if (!_stricmp(szId,"W4220T")) + { + dwResult=PXR412; + } + else + { + if (!_stricmp(szId,"W8220T")) + { + dwResult=PXR412; + } + else + { + szId[5]=0; + if (!_stricmp(szId,"R412C")) + { + dwResult=PXR412; + } + else + { + if (!_stricmp(szId,"R820T")) + { + dwResult=PXR412; + } + else + { + szId[2]=0; + if (!strcmp(szId,"40")) + dwResult=PX40X; + else + { + if (!strcmp(szId,"32")) + dwResult=PX32X; + else + { + if (!strcmp(szId,"20")) + dwResult=PX20X; + else + { + if (!strcmp(szId,"12")) + dwResult=PX12X; + else + { + if (!isdigit(szId[1])) + szId[1]=0; + if (!strcmp(szId,"8")) + dwResult=PX8X; + else + { + if (!strcmp(szId,"6")) + dwResult=PX6X; + else + { + if (!strcmp(szId,"4")) + dwResult=PX4X; + } + } + } + } + } + } + } + } + } + } + return dwResult; +} + +int CSCSICD::GetCurrentSpeed() +{ + TDriveMode ModeSenseData; + int Speed=0; + switch (MapInfo.GetTypMapping(Config.Type)) + { + case CDTYPE_TOSHIBA : + { + Speed=0; + break; + } + case CDTYPE_TOSHNEW : + { + if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,15,0x20,m_hDriveEvent)) + { + Error=CDASPIError; + return 0; + } + int Index=(ModeSenseData[14] & 0x30)>>4; + switch (Index) + { + case 0 : + Speed=2352*75; + break; + case 1 : + Speed=2352*75*4; + break; + case 2 : + Speed=2352*75*4; + break; + case 3 : + Speed=-2; + break; + } + break; + } + case CDTYPE_SONY : + case CDTYPE_RICOH : + case CDTYPE_CYBERDRV : + { + if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,34,0x2A,m_hDriveEvent)) + { + Error=CDASPIError; + return 0; + } + Speed=(ModeSenseData[26]*256+ModeSenseData[27])*1000; + break; + } + case CDTYPE_ATAPI : + { + if (!ATAPIModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,34,0x2A,m_hDriveEvent)) + { + Error=CDASPIError; + return 0; + } + if ((ModeSenseData[8]&0x3F)==0x2A) + Speed=(ModeSenseData[22]*256+ModeSenseData[23])*1000; + else if ((ModeSenseData[4]&0x3F)==0x2A) + Speed=(ModeSenseData[18]*256+ModeSenseData[19])*1000; + else Speed=-1; + break; + } + case CDTYPE_PLEXTOR : + { + DWORD dwModel=GetPlextorModel(&Config); + if (dwModel!=PXR412) + { + if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,16,0x31,m_hDriveEvent)) + { + Error=CDASPIError; + return 0; + } + int Index=ModeSenseData[14]; + switch (dwModel) + { + case PX4X : + { + switch (Index) + { + case 0 : + Speed=2352*75; + break; + case 1 : + Speed=2352*75*2; + break; + case 2 : + Speed=2352*75*4; + break; + default : + Speed=-1; + break; + } + break; + } + case PX6X : + { + switch (Index) + { + case 0 : + Speed=2352*75; + break; + case 1 : + Speed=2352*75*4; + break; + case 2 : + Speed=2352*75*6; + break; + default : + Speed=-1; + break; + } + break; + } + case PX8X : + { + switch (Index) + { + case 0 : + Speed=2352*75; + break; + case 1 : + Speed=2352*75*2; + break; + case 2 : + Speed=2352*75*4; + break; + case 3 : + Speed=2352*75*8; + break; + default : + Speed=-1; + break; + } + break; + } + case PX12X : + { + switch (Index) + { + case 0 : + Speed=2352*75; + break; + case 1 : + Speed=2352*75*2; + break; + case 2 : + Speed=2352*75*4; + break; + case 3 : + Speed=2352*75*8; + break; + case 4 : + Speed=2352*75*8; + break; + case 5 : + Speed=2352*75*12; + break; + default : + Speed=-1; + break; + } + break; + } + case PX20X : + { + switch (Index) + { + case 0 : + Speed=2352*75; + break; + case 1 : + Speed=2352*75*2; + break; + case 2 : + Speed=2352*75*4; + break; + case 3 : + Speed=2352*75*8; + break; + case 4 : + Speed=2352*75*8; + break; + case 5 : + Speed=-2; + break; + case 6 : + Speed=2352*75*12; + break; + default : + Speed=-1; + break; + } + break; + } + case PX32X : + { + switch (Index) + { + case 0 : + Speed=2352*75; + break; + case 1 : + Speed=2352*75*2; + break; + case 2 : + Speed=2352*75*4; + break; + case 3 : + Speed=2352*75*8; + break; + case 4 : + Speed=2352*75*8; + break; + case 5 : + Speed=2352*75*8; + break; + case 6 : + Speed=2352*75*14; + break; + default : + Speed=-1; + break; + } + break; + } + case PX40X : + { + switch (Index) + { + case 0 : + Speed=2352*75; + break; + case 1 : + Speed=2352*75*2; + break; + case 2 : + Speed=2352*75*4; + break; + case 3 : + Speed=2352*75*8; + break; + case 4 : + Speed=2352*75*8; + break; + case 5 : + Speed=2352*75*10; + break; + case 6 : + Speed=2352*75*17; + break; + default : + Speed=-1; + break; + } + break; + } + } + } + else + { + if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,32,0x2A,m_hDriveEvent)) + { + Error=CDASPIError; + return 0; + } + Speed=(ModeSenseData[26]*256+ModeSenseData[27])*1000; + } + break; + } + case CDTYPE_NEC : + { + if (!addModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,12,m_hDriveEvent)) + { + Error=CDASPIError; + return 0; + } +// Speed=ModeSenseData[6] & 0x20; + break; + } + case CDTYPE_PHILIPS : + case CDTYPE_MATSHITA : + { + if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,20,0x23,m_hDriveEvent)) + { + Error=CDASPIError; + return 0; + } + int Index; + if (IsOldPhilips(&Config)) + Index=ModeSenseData[14]; + else + Index=ModeSenseData[16]; + switch (Index) + { + case 0 : + Speed=-1; + break; + case 1 : + Speed=2352*75; + break; + case 2 : + Speed=2352*75*2; + break; + case 4 : + Speed=2352*75*4; + break; + case 6 : + Speed=2352*75*6; + break; + case 8 : + Speed=2352*75*8; + break; + default : + Speed=-2; + } + break; + } + default : + Speed=0; + } + return Speed; +} + +void CSCSICD::SetCurrentSpeed(int Speed) +{ + TDriveMode ModeSenseData; + if (Speed==0) + return; + switch (MapInfo.GetTypMapping(Config.Type)) + { + case CDTYPE_TOSHIBA : + break; + case CDTYPE_TOSHNEW : + { + if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,15,0x20,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + ModeSenseData[0]=0; + int Index; + switch (Speed) + { + case -2 : + Index=3; + break; + case 2352*75 : + Index=0; + break; + case 2352*75*4 : + Index=1; + break; + default : + Index=2; + } + ModeSenseData[14]=(ModeSenseData[14] & 0xcf)|(Index<<4); + if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,15,m_hDriveEvent)) + Error=CDASPIError; + break; + } + case CDTYPE_SONY : + case CDTYPE_RICOH : + case CDTYPE_CYBERDRV : + case CDTYPE_ATAPI : + { + TOpcode OpC; + OpC[0]=0xbb; + OpC[1]=0x00; + OpC[4]=0x00; + OpC[5]=0x00; + OpC[6]=0x00; + OpC[7]=0x00; + OpC[8]=0x00; + OpC[9]=0x00; + OpC[10]=0x00; + OpC[11]=0x00; + int NewSpeed=Speed/1000; + int ModSpeed=NewSpeed*1000; + int Direction=0; + int AktSpeed=0; + int Counter=0; + do + { + Error=CDOK; + Counter++; + NewSpeed+=Direction; + OpC[2]=NewSpeed/256; + OpC[3]=NewSpeed%256; + if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_OUT,OpC,12,NULL,0,m_hDriveEvent)) + Error=CDASPIError; + // Is the speed really the one we have selected? + AktSpeed=GetCurrentSpeed(); + if (!Direction) + { + if (AktSpeed<Speed) + Direction=1; + else if (AktSpeed>Speed) + Direction=-1; + } + } + while ((AktSpeed!=ModSpeed) && NewSpeed && (Counter<3)); + break; + } + case CDTYPE_PLEXTOR : + { + DWORD dwModel=GetPlextorModel(&Config); + if (dwModel!=PXR412) + { + if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,16,0x31,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + int Index; + switch (dwModel) + { + case PX4X : + { + switch (Speed) + { + case 2352*75 : + Index=0; + break; + case 2352*75*2 : + Index=1; + break; + case -1 : + case 2352*75*4 : + Index=2; + break; + default : + Index=-1; + break; + } + break; + } + case PX6X : + { + switch (Speed) + { + case 2352*75 : + Index=0; + break; + case 2352*75*4 : + Index=1; + break; + case -1 : + case 2352*75*6 : + Index=2; + break; + default : + Index=-1; + break; + } + break; + } + case PX8X : + { + switch (Speed) + { + case 2352*75 : + Index=0; + break; + case 2352*75*2 : + Index=1; + break; + case 2352*75*4 : + Index=2; + break; + case -1 : + case 2352*75*8 : + Index=3; + break; + default : + Index=-1; + break; + } + break; + } + case PX12X : + { + switch (Speed) + { + case 2352*75 : + Index=0; + break; + case 2352*75*2 : + Index=1; + break; + case 2352*75*4 : + Index=2; + break; + case 2352*75*8 : + Index=3; + break; + case -1 : + case 2352*75*12 : + Index=5; + break; + default : + Index=-1; + break; + } + break; + } + case PX20X : + { + switch (Speed) + { + case 2352*75 : + Index=0; + break; + case 2352*75*2 : + Index=1; + break; + case 2352*75*4 : + Index=2; + break; + case 2352*75*8 : + Index=3; + break; + case -1 : + case 2352*75*12 : + Index=6; + break; + default : + Index=-1; + break; + } + break; + } + case PX32X : + { + switch (Speed) + { + case 2352*75 : + Index=0; + break; + case 2352*75*2 : + Index=1; + break; + case 2352*75*4 : + Index=2; + break; + case 2352*75*8 : + Index=3; + break; + case -1 : + case 2352*75*14 : + Index=6; + break; + default : + Index=-1; + break; + } + break; + } + case PX40X : + { + switch (Speed) + { + case 2352*75 : + Index=0; + break; + case 2352*75*2 : + Index=1; + break; + case 2352*75*4 : + Index=2; + break; + case 2352*75*8 : + Index=3; + break; + case 2352*75*10 : + Index=5; + break; + case -1 : + case 2352*75*17 : + Index=6; + break; + default : + Index=-1; + break; + } + break; + } + } + if (Index>=0) + { + ModeSenseData[14]=Index; + if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,16,m_hDriveEvent)) + Error=CDASPIError; + } + else + Error=CDASPIError; + } + else + { + TOpcode OpC; + OpC[0]=0xbb; + OpC[1]=0x00; + OpC[4]=0xff; + OpC[5]=0xff; + OpC[6]=0x00; + OpC[7]=0x00; + OpC[8]=0x00; + OpC[9]=0x00; + OpC[10]=0x00; + OpC[11]=0x00; + int NewSpeed=Speed/1000; + int ModSpeed=NewSpeed*1000; + int Direction=0; + int AktSpeed=0; + int Counter=0; + do + { + Error=CDOK; + Counter++; + NewSpeed+=Direction; + OpC[2]=NewSpeed/256; + OpC[3]=NewSpeed%256; + if (!ExecuteSCSIRequest(Config.HostAdapterNumber,Config.ID,Config.LUN,SRB_DIR_OUT,OpC,12,NULL,0,m_hDriveEvent)) + Error=CDASPIError; + // Is the speed really the one we have selected? + AktSpeed=GetCurrentSpeed(); + if (!Direction) + { + if (AktSpeed<Speed) + Direction=1; + else if (AktSpeed>Speed) + Direction=-1; + } + } + while ((AktSpeed!=ModSpeed) && NewSpeed && (Counter<3)); + } + break; + } + case CDTYPE_NEC : + { + if (!addModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,12,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } +// Speed=ModeSenseData[6] & 0x20; + if (!addModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,12,m_hDriveEvent)) + Error=CDASPIError; + break; + } + case CDTYPE_PHILIPS : + case CDTYPE_MATSHITA : + { + if (!ModeSense(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,20,0x23,m_hDriveEvent)) + { + Error=CDASPIError; + return; + } + ModeSenseData[0]=0; + int Index; + switch (Speed) + { + case -2 : + case -1 : + Index=0; + break; + case 2352*75 : + Index=1; + break; + case 2352*75*2 : + Index=2; + break; + case 2352*75*4 : + Index=4; + break; + case 2352*75*6 : + Index=6; + break; + case 2352*75*8 : + Index=8; + break; + default : + Index=0; + } + if (IsOldPhilips(&Config)) + ModeSenseData[14]=Index; + else + ModeSenseData[16]=Index; + if (!ModeSelect(Config.HostAdapterNumber,Config.ID,Config.LUN,ModeSenseData,20,m_hDriveEvent)) + Error=CDASPIError; + break; + } + } +} + +int CSCSICD::GetSpeed(BYTE Index) +{ + if (Index<SupportedSpeeds) + return SpeedTable[Index]; + return 0; +} + + +// ---------------------------------------------------------------------------------------- +// - Implementation of general functions - +// - - +// - Author: Christoph Schmelnik - +// - Purposee: variour initialisations - +// ---------------------------------------------------------------------------------------- + +extern "C" DWORD NtScsiSendASPI32Command( LPSRB lpsrb ); +int LoadASPI2() +{ + OSVERSIONINFO VersionInfo; + VersionInfo.dwOSVersionInfoSize=sizeof(VersionInfo); + GetVersionEx(&VersionInfo); + if (VersionInfo.dwPlatformId==VER_PLATFORM_WIN32_NT) + RunningNT=TRUE; + else + RunningNT=FALSE; + ASPIInstalled=TRUE; + + hDLL=LoadLibrary(L"WNASPI32.DLL"); // load DLL + + if (hDLL==0) + { + if(RunningNT) { + // ok, let's try to see if we can use NT's internal SCSI manager + extern int NtScsiInit( void ); + int nb; + if(nb=NtScsiInit()) { + NumberOfHostAdapters=nb; + SendASPI32Command=(SRBPROC)&NtScsiSendASPI32Command; + return TRUE; + } + } + ASPIInstalled=FALSE; + return FALSE; + } + GetASPI32SupportInfo=(VOIDPROC)GetProcAddress(hDLL,"GetASPI32SupportInfo"); // get Address + SendASPI32Command=(SRBPROC)GetProcAddress(hDLL,"SendASPI32Command"); // get Address + if (GetASPI32SupportInfo==NULL) + { + ASPIInstalled=FALSE; + return FALSE; + } + if (SendASPI32Command==NULL) + { + ASPIInstalled=FALSE; + return FALSE; + } + int r=GetASPI32SupportInfo(); + if (HIBYTE(r)!=SS_COMP) + { + ASPIInstalled=FALSE; + return FALSE; + } + NumberOfHostAdapters=LOBYTE(r); + return TRUE; +} + +int LoadASPI() { + int ret=0; + __try { + ret=LoadASPI2(); + } __except(EXCEPTION_EXECUTE_HANDLER) + { + ret=0; + } + return ret; +} + + +int FreeASPI() +{ + extern int NtScsiDeInit( void ); + NtScsiDeInit(); + if (hDLL) FreeLibrary(hDLL); + hDLL=NULL; + return TRUE; +} + + +int CheckASPI() +{ + return ASPIInstalled; +}
\ No newline at end of file diff --git a/Src/Plugins/Input/in_cdda/windac/Dac32.dsp b/Src/Plugins/Input/in_cdda/windac/Dac32.dsp new file mode 100644 index 00000000..714b0166 --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/Dac32.dsp @@ -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 diff --git a/Src/Plugins/Input/in_cdda/windac/Dac32.h b/Src/Plugins/Input/in_cdda/windac/Dac32.h new file mode 100644 index 00000000..4e4ab624 --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/Dac32.h @@ -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
\ No newline at end of file diff --git a/Src/Plugins/Input/in_cdda/windac/Dac32.mak b/Src/Plugins/Input/in_cdda/windac/Dac32.mak new file mode 100644 index 00000000..46b175f7 --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/Dac32.mak @@ -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 +################################################################################ diff --git a/Src/Plugins/Input/in_cdda/windac/Dac32.rc b/Src/Plugins/Input/in_cdda/windac/Dac32.rc new file mode 100644 index 00000000..1e81aeee --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/Dac32.rc @@ -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 + diff --git a/Src/Plugins/Input/in_cdda/windac/NTScsi.cpp b/Src/Plugins/Input/in_cdda/windac/NTScsi.cpp new file mode 100644 index 00000000..8112b100 --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/NTScsi.cpp @@ -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 ); +}
\ No newline at end of file diff --git a/Src/Plugins/Input/in_cdda/windac/NTScsi.h b/Src/Plugins/Input/in_cdda/windac/NTScsi.h new file mode 100644 index 00000000..895c787d --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/NTScsi.h @@ -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
\ No newline at end of file diff --git a/Src/Plugins/Input/in_cdda/windac/RESOURCE.H b/Src/Plugins/Input/in_cdda/windac/RESOURCE.H new file mode 100644 index 00000000..3a24dff9 --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/RESOURCE.H @@ -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
\ No newline at end of file diff --git a/Src/Plugins/Input/in_cdda/windac/SCSIDEFS.H b/Src/Plugins/Input/in_cdda/windac/SCSIDEFS.H new file mode 100644 index 00000000..5012429f --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/SCSIDEFS.H @@ -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)
\ No newline at end of file diff --git a/Src/Plugins/Input/in_cdda/windac/Winaspi.h b/Src/Plugins/Input/in_cdda/windac/Winaspi.h new file mode 100644 index 00000000..5fc78fe5 --- /dev/null +++ b/Src/Plugins/Input/in_cdda/windac/Winaspi.h @@ -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
\ No newline at end of file |