--- /dev/null
+//
+// OS agnostic CDROM interface functions
+//
+// by James L. Hammons
+//
+// This file is basically a shell to keep the front-end clean and also pull in the
+// appropriate back-end code depending on which target is being compiled for.
+//
+
+#include "cdintf.h" // Every OS has to implement these
+
+/*#ifdef __GCCWIN32__
+#include "cdintf_win32.cpp"
+#endif
+
+#ifdef __GCCUNIX__
+#ifdef _OSX_
+
+#include "cdintf_osx.cpp"
+
+#else
+#include "cdintf_linux.cpp"
+
+#endif
+#endif//*/
+
+#if defined(__GCCWIN32__)
+
+#include "cdintf_win32.cpp"
+
+#elif defined(__GCCUNIX__)
+#if defined(_OSX_)
+
+#include "cdintf_osx.cpp"
+
+#else
+
+#include "cdintf_linux.cpp"
+
+#endif
+#endif
--- /dev/null
+//
+// OS specific CDROM interface (linux)
+//
+// by James L. Hammons
+//
--- /dev/null
+//
+// OS specific CDROM interface (Mac OS X)
+//
+// by ?
+//
--- /dev/null
+//
+// OS specific CDROM interface (Win32)
+//
+// by James L. Hammons
+//
+
+// OS dependent CDROM stuffola
+#include <windows.h>
+#include <stdio.h>
+#include "wnaspi32.h"
+#include "scsidefs.h"
+// End OS dependent
+
+#include "log.h"
+
+using namespace std;
+
+// Local variables
+
+DWORD remain = 0, sector = 0;
+BYTE cdBuf[2532 * 10];
+
+// Private function prototypes
+
+
+HINSTANCE WNASPI32_handle = NULL; //Handle to ASPI for Win32 (WNASPI.DLL)
+//WNASPI.DLL functions
+DWORD (*ASPI_GetASPI32SupportInfo)(VOID);
+DWORD (*ASPI_SendASPI32Command)(LPSRB);
+//BOOL (*ASPI_GetASPI32Buffer)(PASPI32BUFF);
+//BOOL (*ASPI_FreeASPI32Buffer)(PASPI32BUFF);
+//BOOL (*ASPI_TranslateASPI32Address)(PDWORD, PDWORD);
+
+byte DataBuf[2352]; //Buffer for holding data to/from drive
+//************************************************************
+//End of globals
+
+//
+// Load the WNASPI32.DLL and import the required functions, then initialise
+// Win ASPI 32.
+//
+BOOL InitASPI()
+{
+ DWORD dwSupportInfo;
+ SRB_GetSetTimeouts srbTimeouts;
+
+ WNASPI32_handle = LoadLibrary("WNASPI32"); //WNASPI32.DLL
+
+ if (!WNASPI32_handle)
+ {
+ WriteLog("CDINTF: Could not load WNASPI32.DLL\n");
+ return FALSE;
+ };
+
+ /*
+ ** Get the ASPI entry points. Note that only two functions are mandatory:
+ ** GetASPI32SupportInfo and SendASPI32Command. The code will run if the
+ ** others are not present.
+ */
+ ASPI_GetASPI32SupportInfo = (DWORD (*)(void))GetProcAddress(WNASPI32_handle, "GetASPI32SupportInfo");
+ ASPI_SendASPI32Command = (DWORD (*)(LPSRB))GetProcAddress(WNASPI32_handle, "SendASPI32Command");
+ //ASPI_GetASPI32Buffer = (BOOL (*)(PASPI32BUFF))GetProcAddress(WNASPI32_handle, "GetASPI32Buffer");
+ //ASPI_FreeASPI32Buffer = (BOOL (*)(PASPI32BUFF))GetProcAddress(WNASPI32_handle, "FreeASPI32Buffer");
+ //ASPI_TranslateASPI32Address = (BOOL (*)(PDWORD, PDWORD))GetProcAddress(WNASPI32_handle, "TranslateASPI32Address");
+
+ //Check if the 2 functions were imported.
+ if(!ASPI_GetASPI32SupportInfo || !ASPI_SendASPI32Command)
+ {
+ WriteLog("Could not import GetASPI32SupportInfo & SendASPI32Command functions from WNASPI32.DLL\n");
+ return FALSE;
+ };
+
+ //Initialise Win ASPI 32 by calling ASPI_GetASPI32SupportInfo().
+ dwSupportInfo = ASPI_GetASPI32SupportInfo();
+ if (HIBYTE(LOWORD(dwSupportInfo)) != SS_COMP && HIBYTE(LOWORD(dwSupportInfo)) != SS_NO_ADAPTERS)
+ {
+ WriteLog("Could not initialise using GetASPI32SupportInfo function or no adapters\n");
+ return FALSE;
+ };
+
+ /*
+ ** Set timeouts for ALL devices to 15 seconds. Nothing we deal with should
+ ** take that long to do ANYTHING. We are just doing inquiries to most
+ ** devices, and then simple reads to CDs, disks, etc. so 10 seconds (even
+ ** if they have to spin up) should be plenty.
+ */
+ memset(&srbTimeouts, 0, sizeof(SRB_GetSetTimeouts));
+ srbTimeouts.SRB_Cmd = SC_GETSET_TIMEOUTS;
+ srbTimeouts.SRB_HaId = 0xFF;
+ srbTimeouts.SRB_Flags = SRB_DIR_OUT;
+ srbTimeouts.SRB_Target = 0xFF;
+ srbTimeouts.SRB_Lun = 0xFF;
+ srbTimeouts.SRB_Timeout = 15 * 2;
+ ASPI_SendASPI32Command(&srbTimeouts);
+
+ return TRUE;
+};
+
+/*
+ Sends a SRB (SCSI Request Block) to Win ASPI32 driver for processing and
+ waits for completion.
+
+ The SRB contains the CDB (Command Descriptor Block) which has the
+ raw SCSI command/info you want to send to the drive. So effectively
+ this is actually sending the SCSI command to the drive.
+
+ Note that this uses a Windows event to wait for the drive to reply back
+ which is efficient. If an event is not available (which should never
+ happen really) a loop is used to poll for reply back.
+
+ Both methods will wait infinitely - so the drive must reply back otherwise
+ this software will appear to hang. There seems to be no mechanism for
+ cancelling the SRB process - the Win ASPI 32 'SC_ABORT_SRB' command doesn't
+ seem to work.
+*/
+BOOL SendASPICMD_and_wait(BYTE HA_ID, BYTE Target_ID, BYTE SRB_flags, DWORD Buffer_len,
+ PBYTE Buffer, BYTE CDB_len, PBYTE CDB)
+{
+ DWORD dwASPIStatus;
+ HANDLE hevent_SRB; //A handle for a new Windows event
+ SRB_ExecSCSICmd SRB; //The SRB variable with CDB included
+ BOOL b_retry = TRUE;
+
+ //Clear & setup the SRB for this command..
+ memset(&SRB, 0, sizeof(SRB_ExecSCSICmd)); //Set it to zeroes
+ memcpy(SRB.CDBByte, CDB, CDB_len); //Copy CDB into SRB
+
+ SRB.SRB_Cmd = SC_EXEC_SCSI_CMD;
+ SRB.SRB_HaId = HA_ID;
+ SRB.SRB_Target = Target_ID;
+ //SRB.SRB_Lun = 0; //It's already zero
+ SRB.SRB_Flags = SRB_flags;
+ SRB.SRB_BufLen = Buffer_len;
+ SRB.SRB_BufPointer = Buffer;
+ SRB.SRB_SenseLen = SENSE_LEN;
+ SRB.SRB_CDBLen = CDB_len;
+
+ do
+ {
+ /*
+ ** Create an event (if possible) and issue the command. After sending
+ ** the command, wait for completion.
+ */
+ hevent_SRB = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (hevent_SRB)
+ {
+ //Windows event method for waiting - efficient.
+
+ SRB.SRB_Flags |= SRB_EVENT_NOTIFY;
+ SRB.SRB_PostProc = (LPVOID)hevent_SRB;
+
+ //Send the SRB for processing.
+ dwASPIStatus = ASPI_SendASPI32Command((LPSRB)&SRB);
+ if (dwASPIStatus == SS_PENDING)
+ {
+ //Wait for reply back.
+ WaitForSingleObject(hevent_SRB, INFINITE);
+ }
+ CloseHandle(hevent_SRB);
+ }
+ else
+ {
+ //Polling method for waiting - not very efficient.
+
+ //Send the SRB for processing.
+ ASPI_SendASPI32Command((LPSRB)&SRB);
+ //Wait for reply back.
+ while(SRB.SRB_Status == SS_PENDING);
+ };
+
+ /*
+ ** Check for errors. We'll retry on unit attention condition. Anything
+ ** else will generate an error msg.
+ */
+ if (SRB.SRB_Status != SS_COMP)
+ {
+ if (b_retry && (SRB.SRB_TargStat != STATUS_CHKCOND
+ || (SRB.SenseArea[2] & 0x0F) != KEY_UNITATT))
+ b_retry = FALSE;
+ else
+ {
+ WriteLog("SCSI command failed.\n");
+ return FALSE;
+ }
+ }
+ }
+ while (b_retry == FALSE);
+
+ return TRUE;
+};
+
+/*
+ Lists all available CDROM type drives. This includes:
+ - CDROM drives
+ - CD rewriters/Combo
+ - DVD drives
+ - DVD rewriters
+ etc
+
+ It can only list the SCSI IDs not drive letters. Win ASPI 32 does
+ not provide a mechanism for this. You will have to use windows API
+ for this.
+*/
+VOID ListDevices()
+{
+ BYTE HaId;
+ BYTE Target;
+ BYTE MaxHaId;
+ BYTE MaxTarget;
+ BYTE InquiryBuf[36];
+ BYTE InquiryCDB[6];
+ CHAR szVendor[9];
+ CHAR szProduct[17];
+ CHAR szRev[5];
+ BOOL bSRB_exec;
+ DWORD dwASPIStatus;
+ DWORD dwMaxTransferBytes;
+ SRB_HAInquiry srbHAInquiry;
+ SRB_GDEVBlock srbGDEVBlock;
+ DWORD n_CDROM_drives=0; //No of CDROM type drives found.
+
+ //Use support info for host adapter count and loop over all of them.
+ dwASPIStatus = ASPI_GetASPI32SupportInfo();
+ if(HIBYTE(LOWORD(dwASPIStatus)) == SS_COMP)
+ {
+ MaxHaId = LOBYTE(LOWORD(dwASPIStatus));
+ for(HaId = 0; HaId < MaxHaId; HaId++)
+ {
+ /*
+ ** Do a host adapter inquiry to get max target count. If the
+ ** target count isn't 8 or 16 then go with a default of 8.
+ */
+ memset(&srbHAInquiry, 0, sizeof(SRB_HAInquiry));
+ srbHAInquiry.SRB_Cmd = SC_HA_INQUIRY;
+ srbHAInquiry.SRB_HaId = HaId;
+
+ ASPI_SendASPI32Command((LPSRB)&srbHAInquiry);
+ if(srbHAInquiry.SRB_Status != SS_COMP)
+ {
+ continue;
+ };
+
+ MaxTarget = srbHAInquiry.HA_Unique[3];
+ if(MaxTarget != 8 && MaxTarget != 16)
+ {
+ MaxTarget = 8;
+ };
+
+ /*
+ ** Loop over all the targets on this host adapter.
+ */
+ for(Target = 0; Target < MaxTarget; Target++ )
+ {
+ /*
+ ** Issue get device type call to see if there is a device we're
+ ** interested in at this address. We're interested in CDROMs.
+ */
+ memset(&srbGDEVBlock, 0, sizeof(SRB_GDEVBlock));
+ srbGDEVBlock.SRB_Cmd = SC_GET_DEV_TYPE;
+ srbGDEVBlock.SRB_HaId = HaId;
+ srbGDEVBlock.SRB_Target = Target;
+
+ ASPI_SendASPI32Command((LPSRB)&srbGDEVBlock);
+ if(srbGDEVBlock.SRB_Status != SS_COMP ||
+ (srbGDEVBlock.SRB_DeviceType != DTYPE_CDROM))
+ {
+ continue;
+ };
+
+ /*
+ ** Determine the max transfer count of this target. It will
+ ** be the min of the host adapters min count and the size
+ ** of our global transfer buffer.
+ */
+ dwMaxTransferBytes = (DWORD)&srbHAInquiry.HA_Unique[4];
+
+ /*
+ ** Issue an INQUIRY.
+ */
+ memset(InquiryCDB, 0, 6);
+ InquiryCDB[0] = SCSI_INQUIRY;
+ InquiryCDB[4] = 36; //Size in bytes of inquiry buffer.
+
+ //Send SCSI device inquiry command and wait for completion.
+ bSRB_exec = SendASPICMD_and_wait
+ (
+ HaId,
+ Target,
+ SRB_DIR_IN,
+ 36,
+ InquiryBuf,
+ 6,
+ InquiryCDB
+ );
+
+ /*
+ ** Make sure the inquiry worked. If it failed, or if the
+ ** inquiry data returns a different device type than we got
+ ** before (guards against certain device drivers and against
+ ** vendor unique devices).
+ */
+ if(!bSRB_exec || (InquiryBuf[0] != DTYPE_CDROM))
+ continue;
+
+ /*
+ ** Add this target to the screen.
+ */
+ WriteLog("Host adapter ID: %ld\n", HaId);
+ WriteLog("Target ID : %ld\n", Target);
+ WriteLog("LUN ID : 0\n");
+ WriteLog("Max buffer size: %ld bytes\n", dwMaxTransferBytes);
+
+ memcpy(szVendor, InquiryBuf + 8, 8);
+ szVendor[8] = '\0'; //Terminate the string
+
+ memcpy(szProduct, InquiryBuf + 16, 16);
+ szProduct[16] = '\0'; //Terminate the string
+
+ memcpy(szRev, InquiryBuf + 32, 4);
+ szRev[4] = '\0'; //Terminate the string
+
+ WriteLog("Vendor : %s\n", szVendor);
+ WriteLog("Product : %s\n", szProduct);
+ WriteLog("Revision : %s\n\n", szRev);
+
+ n_CDROM_drives++;
+ }
+ }
+
+ if (n_CDROM_drives == 0)
+ WriteLog("No CDROM type drives found.\n");
+ }
+}
+
+//
+// 1. Sets up the CDB for MMC readcd (CDB12) command.
+// 2. Send the request to the drive.
+// 3. If success displays the sector data as hex on the screen.
+//
+BOOL ReadCD(BYTE HA_ID, BYTE Target_ID, long int MMC_LBA_sector)
+{
+ BYTE read_CDB12[12];
+ long int MMC_LBA_sector2;
+
+ //CDB with values for ReadCD CDB12 command. The values were taken from MMC1 draft paper.
+ read_CDB12[0] = 0xBE; //Code for ReadCD CDB12 command
+ read_CDB12[1] = 0;
+
+ read_CDB12[5] = byte(MMC_LBA_sector); //Least sig byte of LBA sector no. to read from CD
+ MMC_LBA_sector2 = MMC_LBA_sector >> 8;
+ read_CDB12[4] = byte(MMC_LBA_sector2); //2nd byte of:
+ MMC_LBA_sector2 = MMC_LBA_sector2 >> 8;
+ read_CDB12[3] = byte(MMC_LBA_sector2); //3rd byte of:
+ MMC_LBA_sector2 = MMC_LBA_sector2 >> 8;
+ read_CDB12[2] = byte(MMC_LBA_sector2); //Most significant byte
+
+ read_CDB12[6] = 0; //No. of sectors to read from CD byte 2 (MSB)
+ read_CDB12[7] = 0; //No. of sectors to read from CD byte 1
+ read_CDB12[8] = 1; //No. of sectors to read from CD byte 0 (LSB)
+ read_CDB12[9] = 0xF8; //Raw read, 2352 bytes per sector
+ read_CDB12[10] = 0; //Sub-channel selection bits.
+ read_CDB12[11] = 0;
+
+ return SendASPICMD_and_wait(HA_ID, Target_ID, SRB_DIR_IN, 2352, DataBuf, 12, read_CDB12);
+}
+
+//
+// Initialize the SDL sound system
+//
+void __CDInit(void)
+{
+ if (!InitASPI())
+ {
+ WriteLog("Sound: Failed to init ASPI layer!\n");
+ exit(1);//bad!
+ }
+}
+
+//
+// Close down the SDL sound subsystem
+//
+void __CDDone(void)
+{
+ //Unload ASPI if it has been loaded.
+ if (WNASPI32_handle)
+ FreeLibrary(WNASPI32_handle);
+}
+
+/*//
+// Sound card callback handler
+//
+void SDLSoundCallback(void * userdata, Uint8 * buffer, int length)
+{
+ if (remain > 0)
+ {
+ memcpy(buffer, DataBuf + 2352 - remain, remain);
+ length -= remain;
+ buffer += remain;
+ remain = 0;
+ }
+
+ while (length > 0)
+ {
+ ReadCD(0, 1, sector++);
+ memcpy(buffer, DataBuf, (length >= 2352 ? 2352 : length));
+ length -= 2352;
+ buffer += 2352;
+ }
+
+ if (length < 0)
+ remain = -length;
+}*/
--- /dev/null
+//***************************************************************************
+//
+// 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_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY)
+#define SCSI_WRITE_BUFF 0x3B // Write Buffer (O)
+
+//***************************************************************************
+// %%% Commands Unique to Direct Access Devices %%%
+//***************************************************************************
+#define SCSI_COMPARE 0x39 // Compare (O)
+#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_RCV_DIAG 0x1C // Receive Diagnostic Results (O)
+#define SCSI_RELEASE 0x17 // Release 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_SEND_DIAG 0x1D // Send Diagnostics (MANDATORY)
+#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_RESERVE 0x16 // Reserve Unit (MANDATORY)
+#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)
+
+//***************************************************************************
+// %%% 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 Postion (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_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_CDROM 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)
--- /dev/null
+/******************************************************************************
+**
+** Module Name: wnaspi32.h
+**
+** Description: Header file for ASPI for Win32. This header includes
+** macro and type declarations, and can be included without
+** modification when using Borland C++ or Microsoft Visual
+** C++ with 32-bit compilation. If you are using a different
+** compiler then you MUST ensure that structures are packed
+** onto byte alignments, and that C++ name mangling is turned
+** off.
+**
+** Notes: This file created using 4 spaces per tab.
+**
+******************************************************************************/
+
+#ifndef __WNASPI32_H__
+#define __WNASPI32_H__
+
+/*
+** Make sure structures are packed and undecorated.
+*/
+
+#ifdef __BORLANDC__
+#pragma option -a1
+#endif //__BORLANDC__
+
+#ifdef _MSC_VER
+#pragma pack(1)
+#endif //__MSC_VER
+
+#ifdef __cplusplus
+extern "C" {
+#endif //__cplusplus
+
+//*****************************************************************************
+// %%% SCSI MISCELLANEOUS EQUATES %%%
+//*****************************************************************************
+
+#define SENSE_LEN 14 // Default sense buffer length
+#define SRB_DIR_SCSI 0x00 // Direction determined by SCSI
+#define SRB_POSTING 0x01 // Enable ASPI posting
+#define SRB_ENABLE_RESIDUAL_COUNT 0x04 // Enable residual byte count reporting
+#define SRB_DIR_IN 0x08 // Transfer from SCSI target to host
+#define SRB_DIR_OUT 0x10 // Transfer from host to SCSI target
+#define SRB_EVENT_NOTIFY 0x40 // Enable ASPI event notification
+
+#define RESIDUAL_COUNT_SUPPORTED 0x02 // Extended buffer flag
+#define MAX_SRB_TIMEOUT 108000lu // 30 hour maximum timeout in s
+#define DEFAULT_SRB_TIMEOUT 108000lu // Max timeout by default
+
+
+//*****************************************************************************
+// %%% 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
+#define SC_SET_HA_PARMS 0x05 // Set HA parameters
+#define SC_GET_DISK_INFO 0x06 // Get Disk information
+#define SC_RESCAN_SCSI_BUS 0x07 // ReBuild SCSI device map
+#define SC_GETSET_TIMEOUTS 0x08 // Get/Set target timeouts
+
+//*****************************************************************************
+// %%% 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 OLD_MANAGER in Win32)
+#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!
+#define SS_MISMATCHED_COMPONENTS 0xE7 // The DLLs/EXEs of ASPI don't version check
+#define SS_NO_ADAPTERS 0xE8 // No host adapters to manage
+#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
+
+//*****************************************************************************
+// %%% 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
+#define HASTAT_TIMEOUT 0x09 // Timed out while SRB was waiting to beprocessed.
+#define HASTAT_COMMAND_TIMEOUT 0x0B // Adapter timed out processing SRB.
+#define HASTAT_MESSAGE_REJECT 0x0D // While processing SRB, the // adapter received a MESSAGE
+#define HASTAT_BUS_RESET 0x0E // A bus reset was detected.
+#define HASTAT_PARITY_ERROR 0x0F // A parity error was detected.
+#define HASTAT_REQUEST_SENSE_FAILED 0x10 // The adapter failed in issuing
+
+//*****************************************************************************
+// %%% SRB - HOST ADAPTER INQUIRY - SC_HA_INQUIRY (0) %%%
+//*****************************************************************************
+
+typedef struct // Offset
+{ // HX/DEC
+ BYTE SRB_Cmd; // 00/000 ASPI command code = SC_HA_INQUIRY
+ BYTE SRB_Status; // 01/001 ASPI command status byte
+ BYTE SRB_HaId; // 02/002 ASPI host adapter number
+ BYTE SRB_Flags; // 03/003 ASPI request flags
+ DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0
+ BYTE HA_Count; // 08/008 Number of host adapters present
+ BYTE HA_SCSI_ID; // 09/009 SCSI ID of host adapter
+ BYTE HA_ManagerId[16]; // 0A/010 String describing the manager
+ BYTE HA_Identifier[16]; // 1A/026 String describing the host adapter
+ BYTE HA_Unique[16]; // 2A/042 Host Adapter Unique parameters
+ WORD HA_Rsvd1; // 3A/058 Reserved, MUST = 0
+}
+SRB_HAInquiry, *PSRB_HAInquiry, FAR *LPSRB_HAInquiry;
+
+//*****************************************************************************
+// %%% SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE (1) %%%
+//*****************************************************************************
+
+typedef struct // Offset
+{ // HX/DEC
+ BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GET_DEV_TYPE
+ 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
+ BYTE SRB_Target; // 08/008 Target's SCSI ID
+ BYTE SRB_Lun; // 09/009 Target's LUN number
+ BYTE SRB_DeviceType; // 0A/010 Target's peripheral device type
+ BYTE SRB_Rsvd1; // 0B/011 Reserved, MUST = 0
+}
+SRB_GDEVBlock, *PSRB_GDEVBlock, FAR *LPSRB_GDEVBlock;
+
+//*****************************************************************************
+// %%% SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD (2) %%%
+//*****************************************************************************
+
+typedef struct // Offset
+{ // HX/DEC
+ BYTE SRB_Cmd; // 00/000 ASPI command code = SC_EXEC_SCSI_CMD
+ BYTE SRB_Status; // 01/001 ASPI command status byte
+ BYTE SRB_HaId; // 02/002 ASPI host adapter number
+ BYTE SRB_Flags; // 03/003 ASPI request flags
+ DWORD SRB_Hdr_Rsvd; // 04/004 Reserved
+ BYTE SRB_Target; // 08/008 Target's SCSI ID
+ BYTE SRB_Lun; // 09/009 Target's LUN number
+ WORD SRB_Rsvd1; // 0A/010 Reserved for Alignment
+ DWORD SRB_BufLen; // 0C/012 Data Allocation Length
+ BYTE FAR *SRB_BufPointer; // 10/016 Data Buffer Pointer
+ BYTE SRB_SenseLen; // 14/020 Sense Allocation Length
+ BYTE SRB_CDBLen; // 15/021 CDB Length
+ BYTE SRB_HaStat; // 16/022 Host Adapter Status
+ BYTE SRB_TargStat; // 17/023 Target Status
+ VOID FAR *SRB_PostProc; // 18/024 Post routine
+ BYTE SRB_Rsvd2[20]; // 1C/028 Reserved, MUST = 0
+ BYTE CDBByte[16]; // 30/048 SCSI CDB
+ BYTE SenseArea[SENSE_LEN+2]; // 50/064 Request Sense buffer
+}
+SRB_ExecSCSICmd, *PSRB_ExecSCSICmd, FAR *LPSRB_ExecSCSICmd;
+
+//*****************************************************************************
+// %%% SRB - ABORT AN SRB - SC_ABORT_SRB (3) %%%
+//*****************************************************************************
+
+typedef struct // Offset
+{ // HX/DEC
+ BYTE SRB_Cmd; // 00/000 ASPI command 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
+ DWORD SRB_Hdr_Rsvd; // 04/004 Reserved
+ VOID FAR *SRB_ToAbort; // 08/008 Pointer to SRB to abort
+}
+SRB_Abort, *PSRB_Abort, FAR *LPSRB_Abort;
+
+//*****************************************************************************
+// %%% SRB - BUS DEVICE RESET - SC_RESET_DEV (4) %%%
+//*****************************************************************************
+
+typedef struct // Offset
+{ // HX/DEC
+ BYTE SRB_Cmd; // 00/000 ASPI command code = SC_RESET_DEV
+ BYTE SRB_Status; // 01/001 ASPI command status byte
+ BYTE SRB_HaId; // 02/002 ASPI host adapter number
+ BYTE SRB_Flags; // 03/003 ASPI request flags
+ DWORD SRB_Hdr_Rsvd; // 04/004 Reserved
+ BYTE SRB_Target; // 08/008 Target's SCSI ID
+ BYTE SRB_Lun; // 09/009 Target's LUN number
+ BYTE SRB_Rsvd1[12]; // 0A/010 Reserved for Alignment
+ BYTE SRB_HaStat; // 16/022 Host Adapter Status
+ BYTE SRB_TargStat; // 17/023 Target Status
+ VOID FAR *SRB_PostProc; // 18/024 Post routine
+ BYTE SRB_Rsvd2[36]; // 1C/028 Reserved, MUST = 0
+}
+SRB_BusDeviceReset, *PSRB_BusDeviceReset, FAR *LPSRB_BusDeviceReset;
+
+//*****************************************************************************
+// %%% SRB - GET DISK INFORMATION - SC_GET_DISK_INFO %%%
+//*****************************************************************************
+
+typedef struct // Offset
+{ // HX/DEC
+ BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GET_DISK_INFO
+ 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
+ BYTE SRB_Target; // 08/008 Target's SCSI ID
+ BYTE SRB_Lun; // 09/009 Target's LUN number
+ BYTE SRB_DriveFlags; // 0A/010 Driver flags
+ BYTE SRB_Int13HDriveInfo; // 0B/011 Host Adapter Status
+ BYTE SRB_Heads; // 0C/012 Preferred number of heads translation
+ BYTE SRB_Sectors; // 0D/013 Preferred number of sectors translation
+ BYTE SRB_Rsvd1[10]; // 0E/014 Reserved, MUST = 0
+}
+SRB_GetDiskInfo, *PSRB_GetDiskInfo, FAR *LPSRB_GetDiskInfo;
+
+//*****************************************************************************
+// %%% SRB - RESCAN SCSI BUS(ES) ON SCSIPORT %%%
+//*****************************************************************************
+
+typedef struct // Offset
+{ // HX/DEC
+ BYTE SRB_Cmd; // 00/000 ASPI command code = SC_RESCAN_SCSI_BUS
+ 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
+}
+SRB_RescanPort, *PSRB_RescanPort, FAR *LPSRB_RescanPort;
+
+//*****************************************************************************
+// %%% SRB - GET/SET TARGET TIMEOUTS %%%
+//*****************************************************************************
+
+typedef struct // Offset
+{ // HX/DEC
+ BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GETSET_TIMEOUTS
+ BYTE SRB_Status; // 01/001 ASPI command status byte
+ BYTE SRB_HaId; // 02/002 ASPI host adapter number
+ BYTE SRB_Flags; // 03/003 ASPI request flags
+ DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0
+ BYTE SRB_Target; // 08/008 Target's SCSI ID
+ BYTE SRB_Lun; // 09/009 Target's LUN number
+ DWORD SRB_Timeout; // 0A/010 Timeout in half seconds
+}
+SRB_GetSetTimeouts, *PSRB_GetSetTimeouts, FAR *LPSRB_GetSetTimeouts;
+
+//*****************************************************************************
+// %%% ASPIBUFF - Structure For Controllng I/O Buffers %%%
+//*****************************************************************************
+
+typedef struct tag_ASPI32BUFF // Offset
+{ // HX/DEC
+ PBYTE AB_BufPointer; // 00/000 Pointer to the ASPI allocated buffer
+ DWORD AB_BufLen; // 04/004 Length in bytes of the buffer
+ DWORD AB_ZeroFill; // 08/008 Flag set to 1 if buffer should be zeroed
+ DWORD AB_Reserved; // 0C/012 Reserved
+}
+ASPI32BUFF, *PASPI32BUFF, FAR *LPASPI32BUFF;
+
+//*****************************************************************************
+// %%% PROTOTYPES - User Callable ASPI for Win32 Functions %%%
+//*****************************************************************************
+
+typedef void *LPSRB;
+
+#if defined(__BORLANDC__)
+
+DWORD _import GetASPI32SupportInfo( void );
+DWORD _import SendASPI32Command( LPSRB );
+BOOL _import GetASPI32Buffer( PASPI32BUFF );
+BOOL _import FreeASPI32Buffer( PASPI32BUFF );
+BOOL _import TranslateASPI32Address( PDWORD, PDWORD );
+
+#elif defined(_MSC_VER)
+
+__declspec(dllimport) DWORD GetASPI32SupportInfo( void );
+__declspec(dllimport) DWORD SendASPI32Command( LPSRB );
+__declspec(dllimport) BOOL GetASPI32Buffer( PASPI32BUFF );
+__declspec(dllimport) BOOL FreeASPI32Buffer( PASPI32BUFF );
+__declspec(dllimport) BOOL TranslateASPI32Address( PDWORD, PDWORD );
+
+#else
+
+extern DWORD GetASPI32SupportInfo( void );
+extern DWORD GetASPI32Command( LPSRB );
+extern BOOL GetASPI32Buffer( PASPI32BUFF );
+extern BOOL FreeASPI32Buffer( PASPI32BUFF );
+extern BOOL TranslateASPI32Address( PDWORD, PDWORD );
+
+#endif
+
+/*
+** Restore compiler default packing and close off the C declarations.
+*/
+
+#ifdef __BORLANDC__
+#pragma option -a.
+#endif //__BORLANDC__
+
+#ifdef _MSC_VER
+#pragma pack()
+#endif //_MSC_VER
+
+#ifdef __cplusplus
+}
+#endif //__cplusplus
+
+#endif //__WNASPI32_H__