From c3bcd6cec5ca8ba99184b8dbe6fd9f71cd175636 Mon Sep 17 00:00:00 2001 From: David Elliott Date: Wed, 8 Mar 2000 19:41:49 +0000 Subject: [PATCH] - Slightly reworked include files (less messy, more straightforward). - Moved DOS ASPI functionality to msdos/dosaspi.c. - Got rid using PROFILE to get SCSI info from wine.conf. - Read scsi info from /proc/scsi/scsi. - Added setting of a reasonable timeout when opening a SCSI device (5 minutes, defined in winescsi.h). - ExecScsiCommand now ALWAYS posts, even on error (which is the correct behavior). --- Makefile.in | 2 - configure | 2 - configure.in | 1 - dlls/Makefile.in | 11 +- dlls/winaspi/.cvsignore | 3 +- dlls/winaspi/Makefile.in | 15 +- dlls/winaspi/aspi.c | 347 +++++++++++++++++++++++ dlls/winaspi/winaspi16.c | 32 +-- dlls/{wnaspi32 => winaspi}/winaspi32.c | 1 + dlls/winaspi/winescsi.h | 101 +++++++ dlls/{wnaspi32 => winaspi}/wnaspi32.spec | 0 dlls/wnaspi32/.cvsignore | 3 - dlls/wnaspi32/Makefile.in | 15 - include/aspi.h | 140 ++++----- include/winaspi.h | 136 ++++++--- include/wnaspi32.h | 149 +++++++--- msdos/Makefile.in | 1 + msdos/dosaspi.c | 209 ++++++++++++++ 18 files changed, 963 insertions(+), 205 deletions(-) create mode 100644 dlls/winaspi/aspi.c rename dlls/{wnaspi32 => winaspi}/winaspi32.c (99%) create mode 100644 dlls/winaspi/winescsi.h rename dlls/{wnaspi32 => winaspi}/wnaspi32.spec (100%) delete mode 100644 dlls/wnaspi32/.cvsignore delete mode 100644 dlls/wnaspi32/Makefile.in create mode 100644 msdos/dosaspi.c diff --git a/Makefile.in b/Makefile.in index 3eef1b49fd4..9bb7b414562 100644 --- a/Makefile.in +++ b/Makefile.in @@ -37,7 +37,6 @@ LIBSUBDIRS = \ dlls/mouse \ dlls/mpr \ dlls/ntdll \ - dlls/winaspi \ files \ graphics \ graphics/enhmetafiledrv \ @@ -114,7 +113,6 @@ LIBOBJS = \ dlls/mouse/mouse.o \ dlls/mpr/mpr.o \ dlls/ntdll/ntdll.o \ - dlls/winaspi/winaspi.o \ files/files.o \ graphics/graphics.o \ graphics/enhmetafiledrv/enhmetafiledrv.o \ diff --git a/configure b/configure index ab5252c8b26..e696ef3cbfc 100755 --- a/configure +++ b/configure @@ -6231,7 +6231,6 @@ dlls/winmm/wavemap/Makefile dlls/winmm/wineoss/Makefile dlls/winsock/Makefile dlls/winspool/Makefile -dlls/wnaspi32/Makefile documentation/Makefile documentation/wine.conf.man documentation/wine.man @@ -6447,7 +6446,6 @@ dlls/winmm/wavemap/Makefile dlls/winmm/wineoss/Makefile dlls/winsock/Makefile dlls/winspool/Makefile -dlls/wnaspi32/Makefile documentation/Makefile documentation/wine.conf.man documentation/wine.man diff --git a/configure.in b/configure.in index fa08d8fd239..adde21a6759 100644 --- a/configure.in +++ b/configure.in @@ -993,7 +993,6 @@ dlls/winmm/wavemap/Makefile dlls/winmm/wineoss/Makefile dlls/winsock/Makefile dlls/winspool/Makefile -dlls/wnaspi32/Makefile documentation/Makefile documentation/wine.conf.man documentation/wine.man diff --git a/dlls/Makefile.in b/dlls/Makefile.in index 9cc7500d917..3cb7a35cd4a 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -35,10 +35,11 @@ DLLFILES = \ version/libversion.@LIBEXT@ \ win32s/libw32skrnl.@LIBEXT@ \ win87em/libwin87em.@LIBEXT@ \ + winaspi/libwnaspi32.@LIBEXT@ \ windebug/libwindebug.@LIBEXT@ \ wing/libwing.@LIBEXT@ \ - winmm/libwinmm.@LIBEXT@ \ winmm/joystick/libjoystick.drv.@LIBEXT@ \ + winmm/libwinmm.@LIBEXT@ \ winmm/mcianim/libmcianim.drv.@LIBEXT@ \ winmm/mciavi/libmciavi.drv.@LIBEXT@ \ winmm/mcicda/libmcicda.drv.@LIBEXT@ \ @@ -48,8 +49,7 @@ DLLFILES = \ winmm/wavemap/libmsacm.drv.@LIBEXT@ \ winmm/wineoss/libwineoss.drv.@LIBEXT@ \ winsock/libwsock32.@LIBEXT@ \ - winspool/libwinspool.@LIBEXT@ \ - wnaspi32/libwnaspi32.@LIBEXT@ + winspool/libwinspool.@LIBEXT@ # extra names for dlls containing multiple spec files EXTRADLLNAMES = \ @@ -72,6 +72,7 @@ EXTRADLLNAMES = \ ver \ w32sys \ win32s16 \ + winaspi \ winsock @MAKE_RULES@ @@ -212,8 +213,8 @@ libwinmm.@LIBEXT@ libmmsystem.@LIBEXT@: winmm/libwinmm.@LIBEXT@ libwinspool.@LIBEXT@: winspool/libwinspool.@LIBEXT@ $(RM) $@ && $(LN_S) winspool/libwinspool.@LIBEXT@ $@ -libwnaspi32.@LIBEXT@: wnaspi32/libwnaspi32.@LIBEXT@ - $(RM) $@ && $(LN_S) wnaspi32/libwnaspi32.@LIBEXT@ $@ +libwnaspi32.@LIBEXT@ libwinaspi.@LIBEXT@: winaspi/libwnaspi32.@LIBEXT@ + $(RM) $@ && $(LN_S) winaspi/libwnaspi32.@LIBEXT@ $@ libwsock32.@LIBEXT@ libwinsock.@LIBEXT@: winsock/libwsock32.@LIBEXT@ $(RM) $@ && $(LN_S) winsock/libwsock32.@LIBEXT@ $@ diff --git a/dlls/winaspi/.cvsignore b/dlls/winaspi/.cvsignore index 227d8393cc8..0fb2dc0aaba 100644 --- a/dlls/winaspi/.cvsignore +++ b/dlls/winaspi/.cvsignore @@ -1,3 +1,4 @@ -Makefile *.spec.c *.spec.glue.s +Makefile +libwnaspi32.so.1.0 diff --git a/dlls/winaspi/Makefile.in b/dlls/winaspi/Makefile.in index c4c9c6af6cd..00398784dfc 100644 --- a/dlls/winaspi/Makefile.in +++ b/dlls/winaspi/Makefile.in @@ -1,17 +1,18 @@ -DEFS = @DLLFLAGS@ -D__WINE__ TOPSRCDIR = @top_srcdir@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ -MODULE = winaspi +MODULE = wnaspi32 +SOVERSION = 1.0 +ALTNAMES = winaspi -SPEC_SRCS = winaspi.spec +SPEC_SRCS = wnaspi32.spec winaspi.spec C_SRCS = \ - winaspi16.c + aspi.c \ + winaspi16.c \ + winaspi32.c -all: $(MODULE).o - -@MAKE_RULES@ +@MAKE_DLL_RULES@ ### Dependencies: diff --git a/dlls/winaspi/aspi.c b/dlls/winaspi/aspi.c new file mode 100644 index 00000000000..dae42fa5d73 --- /dev/null +++ b/dlls/winaspi/aspi.c @@ -0,0 +1,347 @@ +/************************************************************************** +ASPI routines +(C) 2000 David Elliott +Licensed under the WINE (X11) license +*/ + +/* These routines are to be called from either WNASPI32 or WINASPI */ + +/* FIXME: + * - Registry format is stupid for now.. fix that later + * - No way to override automatic /proc detection, maybe provide an + * HKEY_LOCAL_MACHINE\Software\Wine\Wine\Scsi regkey + * - Somewhat debating an #ifdef linux... technically all this code will + * run on another UNIX.. it will fail nicely. + * - Please add support for mapping multiple channels on host adapters to + * aspi controllers, e-mail me if you need help. + */ + +/* +Registry format is currently: +HKEY_DYN_DATA + WineScsi + (default)=number of host adapters + hHHcCCtTTdDD=linux device name +*/ +#include +#include +#include +#include +#include +#include +#include + +#include "debugtools.h" +#include "winreg.h" +#include "winerror.h" +#include "winescsi.h" +#include "file.h" + +DEFAULT_DEBUG_CHANNEL(aspi); + +/* Internal function prototypes */ +static void +SCSI_GetProcinfo(); + +/* Exported functions */ +void +SCSI_Init() +{ + /* For now we just call SCSI_GetProcinfo */ + SCSI_GetProcinfo(); +} + +int +ASPI_GetNumControllers() +{ + HKEY hkeyScsi; + DWORD type = REG_DWORD; + DWORD num_ha = 0; + DWORD cbData = sizeof(num_ha); + + if( RegOpenKeyExA(HKEY_DYN_DATA, KEYNAME_SCSI, 0, KEY_ALL_ACCESS, &hkeyScsi ) != ERROR_SUCCESS ) + { + ERR("Could not open HEKY_DYN_DATA\\%s\n",KEYNAME_SCSI); + return 0; + } + + if( RegQueryValueExA(hkeyScsi, NULL, NULL, &type, (LPBYTE)&num_ha, &cbData ) != ERROR_SUCCESS ) + { + ERR("Could not query value HEKY_DYN_DATA\\%s\n",KEYNAME_SCSI); + num_ha=0; + } + RegCloseKey(hkeyScsi); + FIXME("Please fix to return number of controllers\n"); + TRACE("Returning %ld host adapters\n", num_ha ); + return num_ha; +} + +BOOL +SCSI_GetDeviceName( int h, int c, int t, int d, LPSTR devstr, LPDWORD lpcbData ) +{ + + char idstr[20]; + HKEY hkeyScsi; + DWORD type; + + if( RegOpenKeyExA(HKEY_DYN_DATA, KEYNAME_SCSI, 0, KEY_ALL_ACCESS, &hkeyScsi ) != ERROR_SUCCESS ) + { + ERR("Could not open HEKY_DYN_DATA\\%s\n",KEYNAME_SCSI); + return FALSE; + } + + + sprintf(idstr, "h%02dc%02dt%02dd%02d", h, c, t, d); + + if( RegQueryValueExA(hkeyScsi, idstr, NULL, &type, devstr, lpcbData) != ERROR_SUCCESS ) + { + WARN("Could not query value HKEY_DYN_DATA\\%s\\%s\n",KEYNAME_SCSI, idstr); + RegCloseKey(hkeyScsi); + return FALSE; + } + RegCloseKey(hkeyScsi); + + TRACE("scsi %s: Device name: %s\n",idstr,devstr); + return TRUE; +} + +/* SCSI_GetHCforController + * RETURNS + * HIWORD: Host Adapter + * LOWORD: Channel + */ +DWORD +ASPI_GetHCforController( int controller ) +{ + DWORD retval; + FIXME("Please fix to map each channel of each host adapter to the proper ASPI controller number!\n"); + retval = (controller << 16); + return retval; +}; + +int +SCSI_OpenDevice( int h, int c, int t, int d ) +{ + char devstr[20]; + DWORD cbData = 20; + int fd = -1; + + if(!SCSI_GetDeviceName( h, c, t, d, devstr, &cbData )) + { + WARN("Could not get device name for h%02dc%02dt%02dd%02d\n", h, c, t, d); + return -1; + } + + TRACE("Opening device %s mode O_RDWR\n",devstr); + fd = open(devstr, O_RDWR); + + if( fd < 0 ) + { + TRACE("open failed\n"); + FILE_SetDosError(); /* SetLastError() to errno */ + TRACE("GetLastError: %ld\n", GetLastError()); + } + return fd; +} + +int +SCSI_LinuxSetTimeout( int fd, int timeout ) +{ + int retval; + TRACE("Setting timeout to %d jiffies\n", timeout); + retval=ioctl(fd,SG_SET_TIMEOUT,&timeout); + if(retval) + { + WARN("Could not set timeout errno=%d!\n",errno); + } + return retval; + +} + +/* This function takes care of the write/read to the linux sg device. + * It returns TRUE or FALSE and uses FILE_SetDosError() to convert + * UNIX errno to Windows GetLastError(). The reason for that is that + * several programs will check that error and we might as well set + * it here. We also return the value of the read call in + * lpcbBytesReturned. + */ +BOOL /* NOTE: This function SHOULD BLOCK */ +SCSI_LinuxDeviceIo( int fd, + struct sg_header * lpInBuffer, DWORD cbInBuffer, + struct sg_header * lpOutBuffer, DWORD cbOutBuffer, + LPDWORD lpcbBytesReturned ) +{ + DWORD dwBytes; + DWORD save_error; + + TRACE("Writing to Liunx sg device\n"); + dwBytes = write( fd, lpInBuffer, cbInBuffer ); + if( dwBytes != cbInBuffer ) + { + FILE_SetDosError(); + save_error = GetLastError(); + WARN("Not enough bytes written to scsi device. bytes=%ld .. %ld\n", cbInBuffer, dwBytes ); + if( save_error == ERROR_NOT_ENOUGH_MEMORY ) + MESSAGE("Your Linux kernel was not able to handle the amount of data sent to the scsi device. Try recompiling with a larger SG_BIG_BUFF value (kernel 2.0.x sg.h"); + WARN("error= %ld\n", save_error ); + *lpcbBytesReturned = 0; + return FALSE; + } + + TRACE("Reading reply from Linux sg device\n"); + *lpcbBytesReturned = read( fd, lpOutBuffer, cbOutBuffer ); + if( *lpcbBytesReturned != cbOutBuffer ) + { + FILE_SetDosError(); + save_error = GetLastError(); + WARN("Not enough bytes read from scsi device. bytes=%ld .. %ld\n", cbOutBuffer, *lpcbBytesReturned); + WARN("error= %ld\n", save_error ); + return FALSE; + } + return TRUE; +} + +/* Internal functions */ +struct LinuxProcScsiDevice +{ + int host; + int channel; + int target; + int lun; + char vendor[9]; + char model[17]; + char rev[5]; + char type[33]; + int ansirev; +}; + +static int +SCSI_getprocentry( FILE * procfile, struct LinuxProcScsiDevice * dev ) +{ + int result; + result = fscanf( procfile, + "Host: scsi%d Channel: %d Id: %d Lun: %d\n", + &dev->host, + &dev->channel, + &dev->target, + &dev->lun ); + if( result == EOF ) + return EOF; + if( result != 4 ) + return 0; + result = fscanf( procfile, + " Vendor: %8c Model: %16c Rev: %4c\n", + dev->vendor, + dev->model, + dev->rev ); + if( result != 3 ) + return 0; + + result = fscanf( procfile, + " Type: %32c ANSI SCSI revision: %d\n", + dev->type, + &dev->ansirev ); + if( result != 2 ) + return 0; + /* Since we fscanf with %XXc instead of %s.. put a NULL at end */ + dev->vendor[8] = 0; + dev->model[16] = 0; + dev->rev[4] = 0; + dev->type[32] = 0; + + return 1; +} + +static void +SCSI_printprocentry( const struct LinuxProcScsiDevice * dev ) +{ + TRACE( "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n", + dev->host, + dev->channel, + dev->target, + dev->lun ); + TRACE( " Vendor: %s Model: %s Rev: %s\n", + dev->vendor, + dev->model, + dev->rev ); + TRACE( " Type: %s ANSI SCSI revision: %02d\n", + dev->type, + dev->ansirev ); +} + +static void +SCSI_GetProcinfo() +/* I'll admit, this function is somewhat of a mess... it was originally + * designed to make some sort of linked list then I realized that + * HKEY_DYN_DATA would be a lot less messy + */ +{ + FILE * procfile = NULL; + + int result = 0; + + struct LinuxProcScsiDevice dev; + + char idstr[20]; + char devstr[20]; + + int devnum=0; + int num_ha = 0; + + HKEY hkeyScsi; + DWORD disposition; + + procfile = fopen( "/proc/scsi/scsi", "r" ); + if( !procfile ) + { + ERR("Could not open /proc/scsi/scsi\n"); + return; + } + + result = fscanf( procfile, "Attached devices: \n"); + if( result != 0 ) + { + ERR("Incorrect /proc/scsi/scsi format"); + return; + } + + if( RegCreateKeyExA(HKEY_DYN_DATA, KEYNAME_SCSI, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyScsi, &disposition ) != ERROR_SUCCESS ) + { + ERR("Could not create HEKY_DYN_DATA\\%s\n",KEYNAME_SCSI); + return; + } + + /* Read info for one device */ + while( (result = SCSI_getprocentry(procfile, &dev)) > 0 ) + { + /* Add to registry */ + + sprintf(idstr, "h%02dc%02dt%02dd%02d", dev.host, dev.channel, dev.target, dev.lun); + sprintf(devstr, "/dev/sg%c", 'a'+devnum); + if( RegSetValueExA(hkeyScsi, idstr, 0, REG_SZ, devstr, strlen(devstr)+1 ) != ERROR_SUCCESS ) + { + ERR("Could not set value HEKY_DYN_DATA\\%s\\%s\n",KEYNAME_SCSI, idstr); + } + + /* Debug output */ + SCSI_printprocentry( &dev ); + + /* FIXME: We *REALLY* need number of controllers.. not ha */ + /* num of hostadapters is highest ha + 1 */ + if( dev.host >= num_ha ) + num_ha = dev.host+1; + devnum++; + } /* while(1) */ + if( result != EOF ) + { + ERR("Incorrect /proc/scsi/scsi format"); + } + fclose( procfile ); + if( RegSetValueExA(hkeyScsi, NULL, 0, REG_DWORD, (LPBYTE)&num_ha, sizeof(num_ha) ) != ERROR_SUCCESS ) + { + ERR("Could not set value HEKY_DYN_DATA\\%s\n",KEYNAME_SCSI); + } + RegCloseKey(hkeyScsi); + return; +} + diff --git a/dlls/winaspi/winaspi16.c b/dlls/winaspi/winaspi16.c index 48f1d43aa3a..7bbae1f2c67 100644 --- a/dlls/winaspi/winaspi16.c +++ b/dlls/winaspi/winaspi16.c @@ -12,7 +12,9 @@ #include "winbase.h" #include "aspi.h" +#include "winescsi.h" #include "winaspi.h" +#include "winescsi.h" #include "options.h" #include "heap.h" #include "debugtools.h" @@ -520,33 +522,3 @@ DWORD WINAPI GetASPIDLLVersion16() #endif } - -void WINAPI ASPI_DOS_func(CONTEXT86 *context) -{ - WORD *stack = CTX_SEG_OFF_TO_LIN(context, SS_reg(context), ESP_reg(context)); - DWORD ptrSRB = *(DWORD *)&stack[2]; - - ASPI_SendASPICommand(ptrSRB, ASPI_DOS); - - /* simulate a normal RETF sequence as required by DPMI CallRMProcFar */ - EIP_reg(context) = *(stack++); - CS_reg(context) = *(stack++); - ESP_reg(context) += 2*sizeof(WORD); -} - - -/* returns the address of a real mode callback to ASPI_DOS_func() */ -void ASPI_DOS_HandleInt(CONTEXT86 *context) -{ -#ifdef linux - FARPROC16 *p = (FARPROC16 *)CTX_SEG_OFF_TO_LIN(context, DS_reg(context), EDX_reg(context)); - if ((CX_reg(context) == 4) || (CX_reg(context) == 5)) - { - *p = DPMI_AllocInternalRMCB(ASPI_DOS_func); - TRACE("allocated real mode proc %p\n", *p); - AX_reg(context) = CX_reg(context); - } - else -#endif - SET_CFLAG(context); -} diff --git a/dlls/wnaspi32/winaspi32.c b/dlls/winaspi/winaspi32.c similarity index 99% rename from dlls/wnaspi32/winaspi32.c rename to dlls/winaspi/winaspi32.c index ec226df7a07..f5243dee4ef 100644 --- a/dlls/wnaspi32/winaspi32.c +++ b/dlls/winaspi/winaspi32.c @@ -12,6 +12,7 @@ #include "winbase.h" #include "aspi.h" #include "wnaspi32.h" +#include "winescsi.h" #include "options.h" #include "heap.h" #include "debugtools.h" diff --git a/dlls/winaspi/winescsi.h b/dlls/winaspi/winescsi.h new file mode 100644 index 00000000000..f2fa44956ea --- /dev/null +++ b/dlls/winaspi/winescsi.h @@ -0,0 +1,101 @@ +#ifndef __WINESCSI_H__ +#define __WINESCSI_H__ + +#ifdef linux +/* Copy of info from 2.2.x kernel */ +#define SG_MAX_SENSE 16 /* too little, unlikely to change in 2.2.x */ + +struct sg_header +{ + int pack_len; /* [o] reply_len (ie useless), ignored as input */ + int reply_len; /* [i] max length of expected reply (inc. sg_header) */ + int pack_id; /* [io] id number of packet (use ints >= 0) */ + int result; /* [o] 0==ok, else (+ve) Unix errno (best ignored) */ + unsigned int twelve_byte:1; + /* [i] Force 12 byte command length for group 6 & 7 commands */ + unsigned int target_status:5; /* [o] scsi status from target */ + unsigned int host_status:8; /* [o] host status (see "DID" codes) */ + unsigned int driver_status:8; /* [o] driver status+suggestion */ + unsigned int other_flags:10; /* unused */ + unsigned char sense_buffer[SG_MAX_SENSE]; /* [o] Output in 3 cases: + when target_status is CHECK_CONDITION or + when target_status is COMMAND_TERMINATED or + when (driver_status & DRIVER_SENSE) is true. */ +}; /* This structure is 36 bytes long on i386 */ + +#define SCSI_OFF sizeof(struct sg_header) + +#define SG_SET_TIMEOUT 0x2201 +#define SG_GET_TIMEOUT 0x2202 +#define SCSI_DEFAULT_TIMEOUT 6000*5 /* 5 minutes */ +#endif + + +/* RegKey used for SCSI info under HKEY_DYN_DATA */ +#define KEYNAME_SCSI "WineScsi" + +/* Function prototypes from dlls/wnaspi32/aspi.c */ +void +SCSI_Init(); + +int +ASPI_GetNumControllers(); + +int +SCSI_OpenDevice( int h, int c, int t, int d ); + +int +SCSI_LinuxSetTimeout( int fd, int timeout ); + +BOOL +SCSI_LinuxDeviceIo( int fd, + struct sg_header * lpvInBuffer, DWORD cbInBuffer, + struct sg_header * lpvOutBuffer, DWORD cbOutBuffer, + LPDWORD lpcbBytesReturned ); + +BOOL +SCSI_GetDeviceName(int h, int c, int t, int d, LPSTR devstr, LPDWORD lpcbData); + +DWORD +ASPI_GetHCforController( int controller ); + +/*** This is where we throw some miscellaneous crap ***/ + +#define ASPI_POSTING(prb) (prb->SRB_Flags & 0x1) + +/* WNASPI32/WINASPI defs */ +#define HOST_TO_TARGET(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x2) +#define TARGET_TO_HOST(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x1) +#define NO_DATA_TRANSFERED(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x3) + + +#define INQUIRY_VENDOR 8 + +#define MUSTEK_SCSI_AREA_AND_WINDOWS 0x04 +#define MUSTEK_SCSI_READ_SCANNED_DATA 0x08 +#define MUSTEK_SCSI_GET_IMAGE_STATUS 0x0f +#define MUSTEK_SCSI_ADF_AND_BACKTRACE 0x10 +#define MUSTEK_SCSI_CCD_DISTANCE 0x11 +#define MUSTEK_SCSI_START_STOP 0x1b + + +#define INQURIY_CMDLEN 6 +#define INQURIY_REPLY_LEN 96 +#define INQUIRY_VENDOR 8 + +#define SENSE_BUFFER(prb) (&prb->CDBByte[prb->SRB_CDBLen]) + +/* Just a container for seeing what devices are open */ +struct ASPI_DEVICE_INFO { + struct ASPI_DEVICE_INFO * next; + int fd; + int hostId; + int target; + int lun; +}; + +typedef struct ASPI_DEVICE_INFO ASPI_DEVICE_INFO; + +/*** End Miscellaneous crap ***/ + +#endif /* #ifndef __WINESCSI_H */ diff --git a/dlls/wnaspi32/wnaspi32.spec b/dlls/winaspi/wnaspi32.spec similarity index 100% rename from dlls/wnaspi32/wnaspi32.spec rename to dlls/winaspi/wnaspi32.spec diff --git a/dlls/wnaspi32/.cvsignore b/dlls/wnaspi32/.cvsignore deleted file mode 100644 index 490a329b553..00000000000 --- a/dlls/wnaspi32/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.spec.c -Makefile -libwnaspi32.so.1.0 diff --git a/dlls/wnaspi32/Makefile.in b/dlls/wnaspi32/Makefile.in deleted file mode 100644 index bbbb5f99ba0..00000000000 --- a/dlls/wnaspi32/Makefile.in +++ /dev/null @@ -1,15 +0,0 @@ -TOPSRCDIR = @top_srcdir@ -TOPOBJDIR = ../.. -SRCDIR = @srcdir@ -VPATH = @srcdir@ -MODULE = wnaspi32 -SOVERSION = 1.0 - -SPEC_SRCS = wnaspi32.spec - -C_SRCS = \ - winaspi32.c - -@MAKE_DLL_RULES@ - -### Dependencies: diff --git a/include/aspi.h b/include/aspi.h index 8a005e8d0e5..2e7cd223eb7 100644 --- a/include/aspi.h +++ b/include/aspi.h @@ -1,4 +1,4 @@ -/* ASPI definitions used for both WNASPI16 and WNASPI32 */ +/* ASPI definitions used for both WINASPI and WNASPI32 */ #ifndef __WINE_ASPI_H #define __WINE_ASPI_H @@ -6,33 +6,75 @@ #include "windef.h" #include "pshpack1.h" - -#define SS_PENDING 0x00 -#define SS_COMP 0x01 -#define SS_ABORTED 0x02 -#define SS_ERR 0x04 -#define SS_INVALID_HA 0x81 -#define SS_INVALID_SRB 0xe0 -#define SS_OLD_MANAGE 0xe1 -#define SS_ILLEGAL_MODE 0xe2 -#define SS_NO_ASPI 0xe3 -#define SS_FAILED_INIT 0xe4 -#define SS_ASPI_IS_BUSY 0xe5 -#define SS_BUFFER_TO_BIG 0xe6 - -#define SC_HA_INQUIRY 0x00 -#define SC_GET_DEV_TYPE 0x01 -#define SC_EXEC_SCSI_CMD 0x02 -#define SC_ABORT_SRB 0x03 -#define SC_RESET_DEV 0x04 +#ifdef __cplusplus +extern "C" { +#endif /* #ifdef __cplusplus */ -/* Host adapter status codes */ -#define HASTAT_OK 0x00 -#define HASTAT_SEL_TO 0x11 -#define HASTAT_DO_DU 0x12 -#define HASTAT_BUS_FREE 0x13 -#define HASTAT_PHASE_ERR 0x14 +/* Stuff in BOTH spec */ + +/* SCSI Miscellaneous Stuff */ +#define SENSE_LEN 14 +#define SRB_DIR_SCSI 0x00 +#define SRB_POSTING 0x01 +#define SRB_ENABLE_RESIDUAL_COUNT 0x04 +#define SRB_DIR_IN 0x08 +#define SRB_DIR_OUT 0x10 + +/* ASPI Command Definitions */ +#define SC_HA_INQUIRY 0x00 +#define SC_GET_DEV_TYPE 0x01 +#define SC_EXEC_SCSI_CMD 0x02 +#define SC_ABORT_SRB 0x03 +#define SC_RESET_DEV 0x04 +#define SC_SET_HA_PARMS 0x05 +#define SC_GET_DISK_INFO 0x06 + +/* SRB status codes */ +#define SS_PENDING 0x00 +#define SS_COMP 0x01 +#define SS_ABORTED 0x02 +#define SS_ABORT_FAIL 0x03 +#define SS_ERR 0x04 + +#define SS_INVALID_CMD 0x80 +#define SS_INVALID_HA 0x81 +#define SS_NO_DEVICE 0x82 + +#define SS_INVALID_SRB 0xE0 +#define SS_OLD_MANAGER 0xE1 +#define SS_BUFFER_ALIGN 0xE1 // Win32 +#define SS_ILLEGAL_MODE 0xE2 +#define SS_NO_ASPI 0xE3 +#define SS_FAILED_INIT 0xE4 +#define SS_ASPI_IS_BUSY 0xE5 +#define SS_BUFFER_TO_BIG 0xE6 +#define SS_MISMATCHED_COMPONENTS 0xE7 // DLLs/EXE version mismatch +#define SS_NO_ADAPTERS 0xE8 +#define SS_INSUFFICIENT_RESOURCES 0xE9 +#define SS_ASPI_IS_SHUTDOWN 0xEA +#define SS_BAD_INSTALL 0xEB + + +/* Host status codes */ +#define HASTAT_OK 0x00 +#define HASTAT_SEL_TO 0x11 +#define HASTAT_DO_DU 0x12 +#define HASTAT_BUS_FREE 0x13 +#define HASTAT_PHASE_ERR 0x14 + +#define HASTAT_TIMEOUT 0x09 +#define HASTAT_COMMAND_TIMEOUT 0x0B +#define HASTAT_MESSAGE_REJECT 0x0D +#define HASTAT_BUS_RESET 0x0E +#define HASTAT_PARITY_ERROR 0x0F +#define HASTAT_REQUEST_SENSE_FAILED 0x10 + + + + + +/*********** OLD ****************/ /* Target status codes */ #define STATUS_GOOD 0x00 @@ -40,42 +82,13 @@ #define STATUS_BUSY 0x08 #define STATUS_RESCONF 0x18 -#ifdef linux - -/* This is a duplicate of the sg_header from /usr/src/linux/include/scsi/sg.h - * kernel 2.0.30 - * This will probably break at some point, but for those who don't have - * kernels installed, I think this should still work. - * - */ - -struct sg_header - { - int pack_len; /* length of incoming packet <4096 (including header) */ - int reply_len; /* maximum length <4096 of expected reply */ - int pack_id; /* id number of packet */ - int result; /* 0==ok, otherwise refer to errno codes */ - unsigned int twelve_byte:1; /* Force 12 byte command length for group 6 & 7 -commands */ - unsigned int target_status:5; /* [o] scsi status from target */ - unsigned int host_status:8; /* [o] host status (see "DID" codes) */ - unsigned int driver_status:8; /* [o] driver status+suggestion */ - unsigned int other_flags:10; /* unused */ - unsigned char sense_buffer[16]; /* used only by reads */ - /* command follows then data for command */ - }; - -#define SCSI_OFF sizeof(struct sg_header) -#endif - #define ASPI_POSTING(prb) (prb->SRB_Flags & 0x1) +/* WNASPI32/WINASPI defs */ #define HOST_TO_TARGET(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x2) #define TARGET_TO_HOST(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x1) #define NO_DATA_TRANSFERED(prb) (((prb->SRB_Flags>>3) & 0x3) == 0x3) -#define SRB_ENABLE_RESIDUAL_COUNT 0x4 -#define SRB_EVENT_NOTIFY 0x40 /* Enable ASPI event notification */ #define INQUIRY_VENDOR 8 @@ -107,18 +120,9 @@ commands */ #define SENSE_BUFFER(prb) (&prb->CDBByte[prb->SRB_CDBLen]) - -/* Just a container for seeing what devices are open */ -struct ASPI_DEVICE_INFO { - struct ASPI_DEVICE_INFO * next; - int fd; - int hostId; - int target; - int lun; -}; - -typedef struct ASPI_DEVICE_INFO ASPI_DEVICE_INFO; - +#ifdef __cplusplus +} +#endif /* #ifdef __cplusplus */ #include "poppack.h" #endif diff --git a/include/winaspi.h b/include/winaspi.h index 0be982eec0d..4d79c4c5693 100644 --- a/include/winaspi.h +++ b/include/winaspi.h @@ -1,16 +1,31 @@ -#ifndef __WINE_WINASPI_H -#define __WINE_WINASPI_H +/************************************************************************** + * WINE winaspi.h + * This file should be source compatible with the Adaptec winaspi.h + * All DOS ASPI structures are the same as WINASPI + */ -#include "windef.h" +/* If __WINE__ is not defined, extra typedefs are defined to be + * source compatible with the regular winaspi.h. + */ +#ifndef __WINASPI_H__ +#define __WINASPI_H__ + +#define FAR +/* Include base aspi defs */ +#include "aspi.h" #include "pshpack1.h" +#ifdef __cplusplus +extern "C" { +#endif /* #ifdef __cplusplus */ +/* WINE SCSI Stuff */ #define ASPI_DOS 1 #define ASPI_WIN16 2 -typedef union SRB16 * LPSRB16; +/* SRB HA_INQUIRY */ -typedef struct tagSRB_HaInquiry16 { +struct tagSRB16_HaInquiry { BYTE SRB_Cmd; BYTE SRB_Status; BYTE SRB_HaId; @@ -23,9 +38,22 @@ typedef struct tagSRB_HaInquiry16 { BYTE HA_Identifier[16]; BYTE HA_Unique[16]; BYTE HA_ExtBuffer[4]; -} SRB_HaInquiry16 WINE_PACKED; +} WINE_PACKED; -typedef struct tagSRB_ExecSCSICmd16 { +struct tagSRB16_GDEVBlock { + 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; /* ASPI request flags */ + DWORD SRB_Hdr_Rsvd; /* Reserved, MUST = 0 */ + BYTE SRB_Target; /* Target's SCSI ID */ + BYTE SRB_Lun; /* Target's LUN number */ + BYTE SRB_DeviceType; /* Target's peripheral device type */ +} WINE_PACKED; + + + +struct tagSRB16_ExecSCSICmd { BYTE SRB_Cmd; /* ASPI command code (W) */ BYTE SRB_Status; /* ASPI command status byte (R) */ BYTE SRB_HaId; /* ASPI host adapter number (W) */ @@ -47,18 +75,18 @@ typedef struct tagSRB_ExecSCSICmd16 { * BYTE CDBByte[6]; * SCSI CDB (W) * * BYTE SenseArea6[SENSE_LEN]; * Request Sense buffer (R) * */ -} SRB_ExecSCSICmd16 WINE_PACKED; +} WINE_PACKED; -typedef struct tagSRB_Abort16 { +struct tagSRB16_Abort { 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 */ - LPSRB16 SRB_ToAbort; /* Pointer to SRB to abort */ -} SRB_Abort16 WINE_PACKED; + SEGPTR SRB_ToAbort; /* Pointer to SRB to abort */ +} WINE_PACKED; -typedef struct tagSRB_BusDeviceReset16 { +struct tagSRB16_BusDeviceReset { BYTE SRB_Cmd; /* ASPI command code = SC_RESET_DEV */ BYTE SRB_Status; /* ASPI command status byte */ BYTE SRB_HaId; /* ASPI host adapter number */ @@ -69,35 +97,79 @@ typedef struct tagSRB_BusDeviceReset16 { BYTE SRB_ResetRsvd1[14]; /* Reserved, MUST = 0 */ BYTE SRB_HaStat; /* Host Adapter Status */ BYTE SRB_TargStat; /* Target Status */ - SEGPTR SRB_PostProc; /* Post routine */ + FARPROC16 SRB_PostProc; /* Post routine */ BYTE SRB_ResetRsvd2[34]; /* Reserved, MUST = 0 */ -} SRB_BusDeviceReset16 WINE_PACKED; +} WINE_PACKED; -typedef struct tagSRB_GDEVBlock16 { - BYTE SRB_Cmd; /* ASPI command code = SC_GET_DEV_TYPE */ +struct tagSRB16_Common { + 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 */ - BYTE SRB_Target; /* Target's SCSI ID */ - BYTE SRB_Lun; /* Target's LUN number */ - BYTE SRB_DeviceType; /* Target's peripheral device type */ -} SRB_GDEVBlock16 WINE_PACKED; +} WINE_PACKED; -typedef struct tagSRB_Common16 { - BYTE SRB_Cmd; -} SRB_Common16; - -union SRB16 { - SRB_Common16 common; - SRB_HaInquiry16 inquiry; - SRB_ExecSCSICmd16 cmd; - SRB_Abort16 abort; - SRB_BusDeviceReset16 reset; - SRB_GDEVBlock16 devtype; +union tagSRB16 { + struct tagSRB16_Common common; + struct tagSRB16_HaInquiry inquiry; + struct tagSRB16_ExecSCSICmd cmd; + struct tagSRB16_Abort abort; + struct tagSRB16_BusDeviceReset reset; + struct tagSRB16_GDEVBlock devtype; }; -typedef union SRB16 SRB16; +#ifndef __WINE__ +/* These typedefs would conflict with WNASPI32 typedefs, but + * would make it easier to port WINASPI source to WINE */ +typedef struct tagSRB16_HaInquiry +SRB_HAInquiry, *PSRB_HAInquiry, FAR *LPSRB_HAInquiry; + +typedef struct tagSRB16_GDEVBlock +SRB_GDEVBlock, *PSRB_GDEVBlock, FAR *LPSRB_GDEVBlock; + +typedef struct tagSRB16_ExecSCSICmd +SRB_ExecSCSICmd, *PSRB_ExecSCSICmd, FAR *LPSRB_ExecSCSICmd; + +typedef struct tagSRB16_Abort +SRB_Abort, *PSRB_Abort, FAR *LPSRB_Abort; + +typedef struct tagSRB16_BusDeviceReset +SRB_BusDeviceReset, *PSRB_BusDeviceReset, FAR *LPSRB_BusDeviceReset; + +typedef struct tagSRB16_Common +SRB_Common, *PSRB_Common, FAR *LPSRB_Common; + +typedef union tagSRB16 SRB, FAR *LPSRB; + +extern WORD FAR PASCAL SendASPICommand( LPSRB ); +extern WORD FAR PASCAL GetASPISupportInfo( VOID ); + +#endif + +/* These are the typedefs for WINE */ +typedef struct tagSRB16_HaInquiry +SRB_HAInquiry16, *PSRB_HAInquiry16, FAR *LPSRB_HAInquiry16; + +typedef struct tagSRB16_GDEVBlock +SRB_GDEVBlock16, *PSRB_GDEVBlock16, FAR *LPSRB_GDEVBlock16; + +typedef struct tagSRB16_ExecSCSICmd +SRB_ExecSCSICmd16, *PSRB_ExecSCSICmd16, FAR *LPSRB_ExecSCSICmd16; + +typedef struct tagSRB16_Abort +SRB_Abort16, *PSRB_Abort16, FAR *LPSRB_Abort16; + +typedef struct tagSRB16_BusDeviceReset +SRB_BusDeviceReset16, *PSRB_BusDeviceReset16, FAR *LPSRB_BusDeviceReset16; + +typedef struct tagSRB16_Common +SRB_Common16, *PSRB_Common16, FAR *LPSRB_Common16; + +typedef union tagSRB16 SRB16, FAR *LPSRB16; + +#ifdef __cplusplus +} +#endif /* #ifdef __cplusplus */ #include "poppack.h" diff --git a/include/wnaspi32.h b/include/wnaspi32.h index 8945d30bfc8..c5fc1c6a6c7 100644 --- a/include/wnaspi32.h +++ b/include/wnaspi32.h @@ -1,17 +1,39 @@ -#ifndef __WINE_WNASPI32_H -#define __WINE_WNASPI32_H +#ifndef __WNASPI32_H__ +#define __WNASPI32_H__ -#include "windef.h" +#define FAR +/* This file should be 100% source compatible according to MSes docs and + * Adaptecs docs */ +/* Include base aspi defs */ +#include "aspi.h" #include "pshpack1.h" +#ifdef __cplusplus +extern "C" { +#endif /* #ifdef __cplusplus */ -typedef union SRB * LPSRB; +/* Additional definitions */ +/* SCSI Miscellaneous Stuff */ +#define SRB_EVENT_NOTIFY 0x40 +#define RESIDUAL_COUNT_SUPPORTED 0x02 +#define MAX_SRB_TIMEOUT 1080001u +#define DEFAULT_SRB_TIMEOUT 1080001u -#define SS_INVALID_CMD 0x80 -#define SS_INVALID_HA 0x81 -#define SS_NO_DEVICE 0x82 +/* These are defined by MS but not adaptec */ +#define SRB_DATA_SG_LIST 0x02 +#define WM_ASPIPOST 0x4D42 -typedef struct tagSRB_HaInquiry { + +/* ASPI Command Definitions */ +#define SC_RESCAN_SCSI_BUS 0x07 +#define SC_GETSET_TIMEOUTS 0x08 + +/* SRB Status.. MS defined */ +#define SS_SECURITY_VIOLATION 0xE2 // Replaces SS_INVALID_MODE +/*** END DEFS */ + +/* SRB - HOST ADAPTER INQUIRY - SC_HA_INQUIRY */ +struct tagSRB32_HaInquiry { BYTE SRB_Cmd; /* ASPI command code = SC_HA_INQUIRY */ BYTE SRB_Status; /* ASPI command status byte */ BYTE SRB_HaId; /* ASPI host adapter number */ @@ -23,9 +45,23 @@ typedef struct tagSRB_HaInquiry { BYTE HA_Identifier[16]; /* String describing the host adapter */ BYTE HA_Unique[16]; /* Host Adapter Unique parameters */ WORD HA_Rsvd1; -} SRB_HaInquiry WINE_PACKED; +} WINE_PACKED; -typedef struct tagSRB_ExecSCSICmd { +/* SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE */ +struct tagSRB32_GDEVBlock { + 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; +} WINE_PACKED; + +/* SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD */ +struct tagSRB32_ExecSCSICmd { BYTE SRB_Cmd; /* ASPI command code = SC_EXEC_SCSI_CMD */ BYTE SRB_Status; /* ASPI command status byte */ BYTE SRB_HaId; /* ASPI host adapter number */ @@ -45,18 +81,20 @@ typedef struct tagSRB_ExecSCSICmd { BYTE SRB_Rsvd3[16]; /* Reserved for expansion */ BYTE CDBByte[16]; /* SCSI CDB */ BYTE SenseArea[0]; /* Request sense buffer - var length */ -} SRB_ExecSCSICmd WINE_PACKED; +} WINE_PACKED; -typedef struct tagSRB_Abort { +/* SRB - ABORT AN ARB - SC_ABORT_SRB */ +struct tagSRB32_Abort { 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; /* Reserved */ DWORD SRB_Hdr_Rsvd; /* Reserved, MUST = 0 */ - LPSRB SRB_ToAbort; /* Pointer to SRB to abort */ -} SRB_Abort WINE_PACKED; + VOID FAR *SRB_ToAbort; /* Pointer to SRB to abort */ +} WINE_PACKED; -typedef struct tagSRB_BusDeviceReset { +/* SRB - BUS DEVICE RESET - SC_RESET_DEV */ +struct tagSRB32_BusDeviceReset { BYTE SRB_Cmd; /* ASPI command code = SC_RESET_DEV */ BYTE SRB_Status; /* ASPI command status byte */ BYTE SRB_HaId; /* ASPI host adapter number */ @@ -70,35 +108,68 @@ typedef struct tagSRB_BusDeviceReset { void (*SRB_PostProc)(); /* Post routine */ void *SRB_Rsvd2; /* Reserved */ BYTE SRB_Rsvd3[32]; /* Reserved */ -} SRB_BusDeviceReset WINE_PACKED; +} WINE_PACKED; -typedef struct tagSRB_GDEVBlock { - 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; -} SRB_GDEVBlock WINE_PACKED; +/* SRB - GET DISK INFORMATION - SC_GET_DISK_INFO */ +struct tagSRB32_GetDiskInfo { + 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_DriveFlags; /* Driver flags */ + BYTE SRB_Int13HDriveInfo; /* Host Adapter Status */ + BYTE SRB_Heads; /* Preferred number of heads trans */ + BYTE SRB_Sectors; /* Preferred number of sectors trans */ + BYTE SRB_Rsvd1[10]; /* Reserved */ +} WINE_PACKED; -typedef struct tagSRB_Common { - BYTE SRB_Cmd; -} SRB_Common; +/* SRB header */ +struct tagSRB32_Header { + 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 */ +} WINE_PACKED; -union SRB { - SRB_Common common; - SRB_HaInquiry inquiry; - SRB_ExecSCSICmd cmd; - SRB_Abort abort; - SRB_BusDeviceReset reset; - SRB_GDEVBlock devtype; +union tagSRB32 { + struct tagSRB32_Header common; + struct tagSRB32_HaInquiry inquiry; + struct tagSRB32_ExecSCSICmd cmd; + struct tagSRB32_Abort abort; + struct tagSRB32_BusDeviceReset reset; + struct tagSRB32_GDEVBlock devtype; }; -typedef union SRB SRB; +/* Typedefs */ +#define typedefSRB(name) \ +typedef struct tagSRB32_##name \ +SRB_##name##, *PSRB_##name +typedefSRB(HaInquiry); +typedefSRB(GDEVBlock); +typedefSRB(ExecSCSICmd); +typedefSRB(Abort); +typedefSRB(BusDeviceReset); +typedefSRB(GetDiskInfo); +typedefSRB(Header); +#undef typedefSRB +typedef union tagSRB32 SRB, *PSRB, *LPSRB; + +/* Prototypes */ +extern DWORD __cdecl +SendASPI32Command (PSRB); +extern DWORD WINAPI +GetASPI32SupportInfo (void); +extern DWORD WINAPI +GetASPI32DLLVersion(void); + +#ifdef __cplusplus +} +#endif /* #ifdef __cplusplus */ #include "poppack.h" -#endif /* __WINE_WNASPI32_H */ +#endif /* __WNASPI32_H__ */ diff --git a/msdos/Makefile.in b/msdos/Makefile.in index bc1cae54fe9..e1a2a0f8894 100644 --- a/msdos/Makefile.in +++ b/msdos/Makefile.in @@ -7,6 +7,7 @@ MODULE = msdos C_SRCS = \ devices.c \ + dosaspi.c \ dosconf.c \ dosmem.c \ dpmi.c \ diff --git a/msdos/dosaspi.c b/msdos/dosaspi.c new file mode 100644 index 00000000000..fdf12a58259 --- /dev/null +++ b/msdos/dosaspi.c @@ -0,0 +1,209 @@ +#include "config.h" + +#include "winbase.h" +#include "winaspi.h" +#include "wnaspi32.h" +#include "heap.h" +#include "debugtools.h" +#include "selectors.h" +#include "miscemu.h" /* DOSMEM_* */ +#include "callback.h" +#include "winerror.h" + +DEFAULT_DEBUG_CHANNEL(aspi) + +static HINSTANCE hWNASPI32 = INVALID_HANDLE_VALUE; +static DWORD (__cdecl *pSendASPI32Command) (LPSRB) = NULL; + +static void +DOSASPI_PostProc( SRB_ExecSCSICmd *lpPRB ) +{ + DWORD ptrSRB; + LPSRB16 lpSRB16; + + + memcpy(&ptrSRB,(LPBYTE)(lpPRB+1)+lpPRB->SRB_SenseLen,sizeof(DWORD)); + TRACE("Copying data back to DOS client at 0x%8lx\n",ptrSRB); + lpSRB16 = DOSMEM_MapRealToLinear(ptrSRB); + lpSRB16->cmd.SRB_TargStat = lpPRB->SRB_TargStat; + lpSRB16->cmd.SRB_HaStat = lpPRB->SRB_HaStat; + memcpy((LPBYTE)(lpSRB16+1)+lpSRB16->cmd.SRB_CDBLen,&lpPRB->SenseArea[0],lpSRB16->cmd.SRB_SenseLen); + + /* Now do posting */ + if( lpPRB->SRB_Status == SS_SECURITY_VIOLATION ) + { + /* SS_SECURITY_VIOLATION isn't defined in DOS ASPI */ + TRACE("Returning SS_NO_DEVICE for SS_SECURITY_VIOLATION\n"); + lpPRB->SRB_Status = SS_NO_DEVICE; + } + + lpSRB16->cmd.SRB_Status = lpPRB->SRB_Status; + TRACE("SRB_Status = 0x%x\n", lpPRB->SRB_Status); + + HeapFree(GetProcessHeap(),0,lpPRB); + + if( (lpSRB16->cmd.SRB_Flags & SRB_POSTING) && lpSRB16->cmd.SRB_PostProc ) + { + CONTEXT86 ctx; +/* The stack should look like this on entry to proc + * NOTE: the SDK draws the following diagram bass akwards, use this one + * to avoid being confused. Remember, the act of pushing something on + * an intel stack involves decreasing the stack pointer by the size of + * the data, and then copying the data at the new SP. + */ +/*************************** + * ... Other crap that is already on the stack ... + * Segment of SRB Pointer <- SP+6 + * Offset of SRB Pointer <- SP+4 + * Segment of return address <- SP+2 + * Offset of return address <- SP+0 + */ + /* FIXME: I am about 99% sure what is here is correct, + * but this code has never been tested (and probably + * won't be either until someone finds a DOS program + * that actually uses a Post Routine) */ + + /* Zero everything */ + memset(&ctx, 0, sizeof(ctx)); + /* CS:IP is routine to call */ + CS_reg(&ctx) = SELECTOROF(lpSRB16->cmd.SRB_PostProc); + EIP_reg(&ctx) = OFFSETOF(lpSRB16->cmd.SRB_PostProc); + /* DPMI_CallRMProc will push the pointer to the stack + * it is given (in this case &ptrSRB) with length + * 2*sizeof(WORD), that is, it copies the the contents + * of ptrSRB onto the stack, and decs sp by 2*sizeof(WORD). + * After doing that, it pushes the return address + * onto the stack (so we don't need to worry about that) + * So the stack should be okay for the PostProc + */ + if(DPMI_CallRMProc(&ctx, (LPWORD)&ptrSRB, 2, FALSE)) + { + TRACE("DPMI_CallRMProc returned nonzero (error) status\n"); + } + } /* if ((SRB_Flags&SRB_POSTING) && SRB_PostProc) */ +} + +static +DWORD ASPI_SendASPIDOSCommand(DWORD ptrSRB) +{ + PSRB_ExecSCSICmd lpPRB; + DWORD retval; + union tagSRB16 * lpSRB16; + + lpSRB16 = DOSMEM_MapRealToLinear(ptrSRB); + + retval = SS_ERR; + switch( lpSRB16->common.SRB_Cmd ) + { + case SC_HA_INQUIRY: + TRACE("SC_HA_INQUIRY\n"); + /* Format is identical in this case */ + retval = (*pSendASPI32Command)((LPSRB)lpSRB16); + break; + case SC_GET_DEV_TYPE: + TRACE("SC_GET_DEV_TYPE\n"); + /* Format is identical in this case */ + retval = (*pSendASPI32Command)((LPSRB)lpSRB16); + break; + case SC_EXEC_SCSI_CMD: + TRACE("SC_EXEC_SCSI_CMD\n"); + TRACE("Copying data from DOS client at 0x%8lx\n",ptrSRB); + lpPRB = HeapAlloc(GetProcessHeap(),0,sizeof(SRB)+lpSRB16->cmd.SRB_SenseLen+sizeof(DWORD)); +#define srb_dos_to_w32(name) \ + lpPRB->SRB_##name = lpSRB16->cmd.SRB_##name + + srb_dos_to_w32(Cmd); + srb_dos_to_w32(Status); + srb_dos_to_w32(HaId); + srb_dos_to_w32(BufLen); + srb_dos_to_w32(SenseLen); + srb_dos_to_w32(CDBLen); + srb_dos_to_w32(Target); + srb_dos_to_w32(Lun); +#undef srb_dos_to_w32 + + /* Allow certain flags to go on to WNASPI32, we also need + * to make sure SRB_POSTING is enabled */ + lpPRB->SRB_Flags = SRB_POSTING | (lpSRB16->cmd.SRB_Flags&(SRB_DIR_IN|SRB_DIR_OUT|SRB_ENABLE_RESIDUAL_COUNT)); + + /* Pointer to data buffer */ + lpPRB->SRB_BufPointer = DOSMEM_MapRealToLinear(lpSRB16->cmd.SRB_BufPointer); + /* Copy CDB in */ + memcpy(&lpPRB->CDBByte[0],&lpSRB16->cmd.CDBByte[0],lpSRB16->cmd.SRB_CDBLen); + + /* Set post proc to our post proc */ + lpPRB->SRB_PostProc = &DOSASPI_PostProc; + + /* Stick the DWORD after all the sense info */ + memcpy((LPBYTE)(lpPRB+1)+lpPRB->SRB_SenseLen,&ptrSRB,sizeof(DWORD)); + retval = (*pSendASPI32Command)((LPSRB)lpPRB); + break; + case SC_ABORT_SRB: + TRACE("SC_ABORT_SRB\n"); + /* Would need some sort of table of active shit */ + break; + case SC_RESET_DEV: + TRACE("SC_RESET_DEV\n"); + break; + default: + TRACE("Unkown command code\n"); + break; + } + + TRACE("Returning %lx\n", retval ); + return retval; +} + +void WINAPI ASPI_DOS_func(CONTEXT86 *context) +{ + WORD *stack = CTX_SEG_OFF_TO_LIN(context, SS_reg(context), ESP_reg(context)); + DWORD ptrSRB = *(DWORD *)&stack[2]; + + ASPI_SendASPIDOSCommand(ptrSRB); + + /* simulate a normal RETF sequence as required by DPMI CallRMProcFar */ + EIP_reg(context) = *(stack++); + CS_reg(context) = *(stack++); + ESP_reg(context) += 2*sizeof(WORD); +} + + +/* returns the address of a real mode callback to ASPI_DOS_func() */ +void ASPI_DOS_HandleInt(CONTEXT86 *context) +{ + FARPROC16 *p = (FARPROC16 *)CTX_SEG_OFF_TO_LIN(context, DS_reg(context), EDX_reg(context)); + TRACE("DOS ASPI opening\n"); + if ((CX_reg(context) == 4) || (CX_reg(context) == 5)) + { + if( hWNASPI32 == INVALID_HANDLE_VALUE ) + { + TRACE("Loading WNASPI32\n"); + hWNASPI32 = LoadLibraryExA("WNASPI32", NULL, 0); + } + + if( hWNASPI32 == INVALID_HANDLE_VALUE ) + { + ERR("Error loading WNASPI32\n"); + goto error_exit; + } + + /* Get SendASPI32Command by Ordinal 2 */ + /* Cast to correct argument/return types */ + pSendASPI32Command = (DWORD (*)(LPSRB))GetProcAddress(hWNASPI32, (LPBYTE)2); + if( !pSendASPI32Command ) + { + ERR("Error getting ordinal 2 from WNASPI32\n"); + goto error_exit; + } + + *p = DPMI_AllocInternalRMCB(ASPI_DOS_func); + TRACE("allocated real mode proc %p\n", *p); + AX_reg(context) = CX_reg(context); + + return; + } +error_exit: + /* Return some error... General Failure sounds okay */ + AX_reg(context) = ERROR_GEN_FAILURE; + SET_CFLAG(context); +}