- 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).
diff --git a/Makefile.in b/Makefile.in
index 3eef1b4..9bb7b41 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -37,7 +37,6 @@
dlls/mouse \
dlls/mpr \
dlls/ntdll \
- dlls/winaspi \
files \
graphics \
graphics/enhmetafiledrv \
@@ -114,7 +113,6 @@
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 ab5252c..e696ef3 100755
--- a/configure
+++ b/configure
@@ -6231,7 +6231,6 @@
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/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 fa08d8f..adde21a 100644
--- a/configure.in
+++ b/configure.in
@@ -993,7 +993,6 @@
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 9cc7500..3cb7a35 100644
--- a/dlls/Makefile.in
+++ b/dlls/Makefile.in
@@ -35,10 +35,11 @@
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 @@
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 @@
ver \
w32sys \
win32s16 \
+ winaspi \
winsock
@MAKE_RULES@
@@ -212,8 +213,8 @@
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 227d839..0fb2dc0 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 c4c9c6a..0039878 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 0000000..dae42fa
--- /dev/null
+++ b/dlls/winaspi/aspi.c
@@ -0,0 +1,347 @@
+/**************************************************************************
+ASPI routines
+(C) 2000 David Elliott <dfe@netnitco.net>
+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 <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#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 48f1d43..7bbae1f 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 @@
#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 ec226df..f5243de 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 0000000..f2fa449
--- /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 490a329..0000000
--- 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 bbbb5f9..0000000
--- 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 8a005e8..2e7cd22 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 @@
#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 0be982e..4d79c4c 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 @@
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 @@
* 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 @@
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 8945d30..c5fc1c6 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 @@
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 @@
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 @@
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 bc1cae5..e1a2a0f 100644
--- a/msdos/Makefile.in
+++ b/msdos/Makefile.in
@@ -7,6 +7,7 @@
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 0000000..fdf12a5
--- /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);
+}