📄 aspilib.c
字号:
/*
* aspilib.c - Copyright (C) 1999 Jay A. Key
*
* Generic routines to access wnaspi32.dll
*
**********************************************************************
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
**********************************************************************
*
* $Id: aspilib.c,v 1.2 2000/02/25 10:47:37 akey Exp $
* $Date: 2000/02/25 10:47:37 $
* $Locker: $
* $Log: aspilib.c,v $
* Revision 1.2 2000/02/25 10:47:37 akey
* sync'ed with akrip32.dll v0.94
*
* Revision 1.7 2000/02/25 10:14:36 akey
* v0.94 release
*
* Revision 1.6 2000/02/14 09:56:25 akey
* cleaned up #ifdef _DEBUG code considerably
*
* Revision 1.5 2000/02/11 10:00:35 akey
* added access to cdplayer.ini
*
* Revision 1.4 2000/01/31 15:35:40 akey
* v0.93: added CDDBGetServerList and fixed problem with Win2000 scsi pass through code
*
* Revision 1.3 2000/01/12 10:07:41 akey
* Added minimal SCSI passthrough IOCTL support
*
* Revision 1.2 2000/01/03 12:29:43 akey
* v0.91 release -- added CDDB and bug fixes
*
*
*/
#define _AKRIP32_
#include <windows.h>
#include <stdio.h>
#include "aspilib.h"
#include "scsidefs.h"
typedef union {
CDHANDLEREC cdHandles[MAXCDHAND];
HANDLE cdMutex[MAXCDHAND];
int nextHandle;
} AKSHAREDMEM, FAR *LPAKSHAREDMEM;
DWORD deinitREAD10( HCDROM hCD );
DWORD initREAD10( HCDROM hCD );
DWORD readCDParameters( HCDROM hCD, BOOL bChangeMask );
DWORD setCDSpeed( HCDROM hCD, DWORD speed );
DWORD pauseResumeCD( HCDROM hCD, BOOL bPause );
DWORD startStopUnit( HCDROM hCD, BOOL bLoEj, BOOL bStart );
int loadAspi( void );
void unloadAspi( void );
BOOL initMutexes( void );
BOOL deinitMutexes( void );
DWORD CDDBSum( DWORD n );
int compBuf( BYTE *b1, BYTE *b2, int n );
DWORD testReadCDAudio( HCDROM hCD, LPTRACKBUF t );
DWORD dummyGetASPI32SupportInfo( void );
DWORD dummySendASPI32Command( LPSRB lpsrb );
BOOL dummyGetASPI32Buffer( PASPI32BUFF pbuf );
BOOL dummyFreeASPI32Buffer( PASPI32BUFF pbuf );
BOOL dummyTranslateASPI32Address( PDWORD p1, PDWORD p2 );
DWORD dummyGetASPI32DLLVersion( void );
int InitSCSIPT( void );
int DeinitSCSIPT( void );
DWORD SPTIGetASPI32SupportInfo( void );
DWORD SPTISendASPI32Command( LPSRB lpsrb );
/*
* static variables
*/
static char *copyrightInfo = "Released under the GNU Lesser General Public License (http://www.fsf.org/).";
static char *aSCSIDevTypes[] = {
"Direct-access device",
"Sequential-access device",
"Printer device",
"Processor device",
"Write-once device",
"CD-ROM device",
"Scanner device",
"Optical memory device",
"Medium changer device",
"Communication device",
"ASC IT8 device",
"ASC IT8 device"
};
#define MAXCDTYPE 8
static CDREADFN aReadFn[] = {
NULL, readCDAudioLBA_ATAPI, readCDAudioLBA_ATAPI, readCDAudioLBA_READ10,
readCDAudioLBA_READ10, readCDAudioLBA_D8, readCDAudioLBA_D4,
readCDAudioLBA_D4, readCDAudioLBA_READ10
};
static HINSTANCE hinstWNASPI32 = NULL;
int alErrCode = 0;
BYTE alAspiErr = 0;
static LPAKSHAREDMEM pcdShared;
CDHANDLEREC *cdHandles;
HANDLE *cdMutexes;
int *nextHandle = NULL;
CRITICAL_SECTION getHandle;
HANDLE hCacheMutex = NULL;
CRITICAL_SECTION csCache;
//CRITICAL_SECTION useDbbuf;
//char dbbuf[512];
#define MAJVER 0
#define MINVER 94
DWORD (*pfnGetASPI32SupportInfo)(void);
DWORD (*pfnSendASPI32Command)(LPSRB);
BOOL (*pfnGetASPI32Buffer)(PASPI32BUFF);
BOOL (*pfnFreeASPI32Buffer)(PASPI32BUFF);
BOOL (*pfnTranslateASPI32Address)(PDWORD,PDWORD);
DWORD (*pfnGetASPI32DLLVersion)(void);
BOOL aspiLoaded = FALSE;
/*
* local prototypes
*/
static char *devType( int i );
/***************************************************************************
* DllMain
***************************************************************************/
BOOL WINAPI DllMain( HANDLE hModule, DWORD dwReason, LPVOID lpReserved )
{
BOOL fInit;
static HANDLE hMapObject = NULL;
HANDLE hInitMutex = NULL;
BOOL retVal = FALSE;
hModule = hModule;
lpReserved = lpReserved;
hInitMutex = CreateMutex( NULL, FALSE, "AKRipDllMainMutex" );
if ( !hInitMutex )
{
dwReason = 0xFFFFFFFF; // do not execute any attach/detach code
}
else if ( WaitForSingleObject( hInitMutex, 15 * 1000 ) != WAIT_OBJECT_0 )
{
CloseHandle( hInitMutex );
dwReason = 0xFFFFFFFF; // do not execute any attach/detach code
}
switch( dwReason )
{
case DLL_PROCESS_ATTACH:
//InitializeCriticalSection( &useDbbuf );
InitializeCriticalSection( &getHandle );
#ifdef _DBLIBMAIN
dbprintf( "akrip32: DLL_PROCESS_ATTACH (hModule=%04X)", hModule );
#endif
loadAspi();
hMapObject = CreateFileMapping( (HANDLE)0xFFFFFFFF, NULL,
PAGE_READWRITE, 0, sizeof(AKSHAREDMEM),
"akrip32memmap" );
if ( hMapObject == NULL )
break;
fInit = ( GetLastError() != ERROR_ALREADY_EXISTS );
pcdShared = MapViewOfFile( hMapObject, FILE_MAP_WRITE, 0, 0, 0 );
if ( !pcdShared )
break;
if ( fInit )
memset( pcdShared, 0, sizeof(AKSHAREDMEM) );
cdHandles = pcdShared->cdHandles;
cdMutexes = pcdShared->cdMutex;
nextHandle = &(pcdShared->nextHandle);
initMutexes( );
retVal = TRUE;
break;
case DLL_THREAD_ATTACH:
#ifdef _DBLIBMAIN
dbprintf( "akrip32: DLL_THREAD_ATTACH (hModule=%04X)", hModule );
#endif
retVal = TRUE;
break;
case DLL_THREAD_DETACH:
#ifdef _DBLIBMAIN
dbprintf( "akrip32: DLL_THREAD_DETACH (hModule=%04X)", hModule );
#endif
retVal = TRUE;
break;
case DLL_PROCESS_DETACH:
#ifdef _DBLIBMAIN
OutputDebugString( "akrip32: DLL_PROCESS_DETACH" );
#endif
deinitMutexes();
UnmapViewOfFile( pcdShared );
CloseHandle( hMapObject );
unloadAspi();
retVal = TRUE;
break;
}
if ( hInitMutex )
{
ReleaseMutex( hInitMutex );
CloseHandle( hInitMutex );
}
return retVal;
}
BOOL initMutexes( void )
{
int i;
char tmp[32];
for( i = 0; i < MAXCDHAND; i++ )
{
wsprintf( tmp, "akrip32_cdMtx%02d", i );
cdMutexes[i] = CreateMutex( NULL, FALSE, tmp );
if ( !cdMutexes[i] )
return FALSE;
}
hCacheMutex = CreateMutex( NULL, FALSE, "AKRipCacheMutex" );
InitializeCriticalSection( &csCache );
return TRUE;
}
BOOL deinitMutexes( void )
{
int i;
for( i = 0; i < MAXCDHAND; i++ )
{
if ( cdMutexes[i] )
CloseHandle( cdMutexes[i] );
}
if ( hCacheMutex )
CloseHandle( hCacheMutex );
DeleteCriticalSection( &csCache );
return TRUE;
}
static char *devType( int i )
{
if ( i >= 0x20 )
return "";
if ( i == 0x1F )
return "Unknown or no device";
if ( i >= 0x0C )
return "";
return aSCSIDevTypes[i];
}
/*
* Assumes that loadAspi has already been called
*/
int getSCSIDevType( BYTE bHostAdapter, BYTE bTarget, BYTE bLUN,
LPBYTE pDevType, LPSTR lpDevTypeStr, int iDevTypeLen )
{
SRB_GDEVBlock s;
DWORD dwStatus;
memset( &s, 0, sizeof(SRB_GDEVBlock) );
s.SRB_Cmd = SC_GET_DEV_TYPE;
s.SRB_HaID = bHostAdapter;
s.SRB_Target = bTarget;
s.SRB_Lun = bLUN;
//DebugBreak();
dwStatus = pfnSendASPI32Command( (LPSRB)&s );
switch( dwStatus )
{
case SS_COMP:
#ifdef _DEBUG
dbprintf( "akrip32: getSCSIDevType() -> SS_COMP: %04X",
s.SRB_DeviceType );
dbprintf( "akrip32: getSCSIDevType(): pDevType == 0x%08X", pDevType );
#endif
if ( pDevType )
*pDevType = s.SRB_DeviceType;
if ( lpDevTypeStr )
strncpy( lpDevTypeStr, devType( s.SRB_DeviceType ), iDevTypeLen );
break;
case SS_NO_DEVICE:
#ifdef _DEBUG
dbprintf( "akrip32: getSCSIDevType() -> SS_NO_DEVICE" );
#endif
if ( pDevType )
*pDevType = 0x1F;
if ( lpDevTypeStr )
strncpy( lpDevTypeStr, "SS_NO_DEVICE", iDevTypeLen );
return FALSE;
default:
#ifdef _DEBUG
dbprintf( "akrip32: getSCSIDevType(): unexpected return from ASPI (%04X)", dwStatus );
#endif
if ( pDevType )
*pDevType = 0x1F;
if ( lpDevTypeStr )
strncpy( lpDevTypeStr, "Unknown return", iDevTypeLen );
return FALSE;
}
return TRUE;
}
DWORD dummyGetASPI32SupportInfo( void )
{
return SS_NO_ASPI;
}
DWORD dummySendASPI32Command( LPSRB lpsrb )
{
lpsrb->SRB_Status = SS_NO_ASPI;
return SS_NO_ASPI;
}
BOOL dummyGetASPI32Buffer( PASPI32BUFF pbuf )
{
return FALSE;
}
BOOL dummyFreeASPI32Buffer( PASPI32BUFF pbuf )
{
return FALSE;
}
BOOL dummyTranslateASPI32Address( PDWORD p1, PDWORD p2 )
{
return FALSE;
}
DWORD dummyGetASPI32DLLVersion( void )
{
return 0;
}
/***************************************************************************
* int loadAspi( void )
***************************************************************************/
int loadAspi( void )
{
DWORD dwErr;
hinstWNASPI32 = LoadLibrary( "WNASPI32.DLL" );
if ( hinstWNASPI32 )
{
pfnGetASPI32SupportInfo =
(DWORD(*)(void))GetProcAddress( hinstWNASPI32, "GetASPI32SupportInfo" );
pfnSendASPI32Command =
(DWORD(*)(LPSRB))GetProcAddress( hinstWNASPI32, "SendASPI32Command" );
pfnGetASPI32Buffer =
(BOOL(*)(PASPI32BUFF))GetProcAddress( hinstWNASPI32, "GetASPI32Buffer" );
pfnFreeASPI32Buffer =
(BOOL(*)(PASPI32BUFF))GetProcAddress( hinstWNASPI32, "FreeASPI32Buffer" );
pfnTranslateASPI32Address =
(BOOL(*)(PDWORD,PDWORD))GetProcAddress( hinstWNASPI32, "TranslateASPI32Address" );
pfnGetASPI32DLLVersion =
(DWORD(*)(void))GetProcAddress( hinstWNASPI32, "GetASPI32DLLVersion" );
if ( !pfnGetASPI32SupportInfo || !pfnSendASPI32Command )
{
if ( !pfnGetASPI32SupportInfo )
alErrCode = ALERR_NOGETASPI32SUPP;
else
alErrCode = ALERR_NOSENDASPICMD;
#ifdef _DEBUG
dbprintf( "akrip32: GetASPI32SupportInfo == 0x%08X",
pfnGetASPI32SupportInfo );
dbprintf( "akrip32: SendASPI32Command == 0x%08X", pfnSendASPI32Command );
#endif
return 0;
}
}
else if ( InitSCSIPT() )
{
pfnGetASPI32SupportInfo = SPTIGetASPI32SupportInfo;
pfnSendASPI32Command = SPTISendASPI32Command;
}
else
{
dwErr = GetLastError();
alErrCode = ALERR_NOWNASPI;
pfnGetASPI32SupportInfo = dummyGetASPI32SupportInfo;
pfnSendASPI32Command = dummySendASPI32Command;
pfnGetASPI32Buffer = dummyGetASPI32Buffer;
pfnFreeASPI32Buffer = dummyFreeASPI32Buffer;
pfnTranslateASPI32Address = dummyTranslateASPI32Address;
pfnGetASPI32DLLVersion = dummyGetASPI32DLLVersion;
#ifdef _DEBUG
dwErr = GetLastError();
dbprintf( "Unable to load WNASPI32.DLL" );
dbprintf( "akrip32: GetLastError() -> %d (%04X)", dwErr, dwErr );
#endif
return 0;
}
aspiLoaded = TRUE;
return 1;
}
void unloadAspi( void )
{
DeinitSCSIPT();
if ( hinstWNASPI32 )
{
aspiLoaded = FALSE;
pfnGetASPI32SupportInfo = NULL;
pfnSendASPI32Command = NULL;
pfnGetASPI32Buffer = NULL;
pfnFreeASPI32Buffer = NULL;
pfnTranslateASPI32Address = NULL;
pfnGetASPI32DLLVersion = NULL;
FreeLibrary( hinstWNASPI32 );
hinstWNASPI32 = NULL;
}
}
/***************************************************************************
* GetNumAdapters
***************************************************************************/
int GetNumAdapters( void )
{
DWORD d;
BYTE bHACount;
BYTE bASPIStatus;
d = pfnGetASPI32SupportInfo();
bASPIStatus = HIBYTE(LOWORD(d));
bHACount = LOBYTE(LOWORD(d));
if ( bASPIStatus != SS_COMP && bASPIStatus != SS_NO_ADAPTERS )
{
alErrCode = ALERR_ASPI;
alAspiErr = bASPIStatus;
#ifdef _DEBUG
dbprintf( "akrip32: GetNumAdapters: bASPIStatus == 0x%02X", bASPIStatus );
#endif
return -1;
}
return (int)bHACount;
}
/***************************************************************************
* GetDriveInfo
***************************************************************************/
DWORD GetDriveInfo( BYTE ha, BYTE tgt, BYTE lun, LPCDREC cdrec )
{
DWORD dwStatus;
HANDLE heventSRB;
SRB_ExecSCSICmd s;
BYTE buf[100];
char outBuf[101];
CDREC cdrecTmp;
heventSRB = CreateEvent( NULL, TRUE, FALSE, NULL );
if ( cdrec )
cdrecTmp = *cdrec;
memset( &cdrecTmp.info, 0, sizeof(CDINFO) );
memset( &s, 0, sizeof( s ) );
memset( buf, 0, 100 );
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
s.SRB_HaID = ha;
s.SRB_Target = tgt;
s.SRB_Lun = lun;
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
s.SRB_BufLen = 100;
s.SRB_BufPointer = buf;
s.SRB_SenseLen = SENSE_LEN;
s.SRB_CDBLen = 6;
s.SRB_PostProc = (LPVOID)heventSRB;
s.CDBByte[0] = SCSI_INQUIRY;
s.CDBByte[4] = 100;
ResetEvent( heventSRB );
dwStatus = pfnSendASPI32Command( (LPSRB)&s );
if ( dwStatus == SS_PENDING )
{
WaitForSingleObject( heventSRB, DEFWAITLEN );
}
CloseHandle( heventSRB );
if ( s.SRB_Status != SS_COMP )
{
alErrCode = ALERR_ASPI;
alAspiErr = s.SRB_Status;
#ifdef _DEBUG
dbprintf( "akrip32: GetDriveInfo: Error status: 0x%04X\n", s.SRB_Status );
#endif
return SS_ERR;
}
#ifdef _DEBUG
{
FILE *fp = fopen( "inquiry.dat", "wb" );
fwrite( buf, 1, 100, fp );
fclose( fp );
}
#endif
memcpy( cdrecTmp.info.vendor, &buf[8], 8 );
memcpy( cdrecTmp.info.prodId, &buf[16], 16 );
memcpy( cdrecTmp.info.rev, &buf[32], 4 );
memcpy( cdrecTmp.info.vendSpec, &buf[36], 20 );
wsprintf( outBuf, "%s, %s v%s (%d:%d:%d)",
cdrecTmp.info.vendor, cdrecTmp.info.prodId, cdrecTmp.info.rev,
ha, tgt, lun );
#ifdef _DEBUG
dbprintf( "akrip32: GetDriveInfo: %s", outBuf );
#endif
strncpy( cdrecTmp.id, outBuf, MAXIDLEN );
cdrecTmp.id[MAXIDLEN] = 0;
if ( cdrec )
*cdrec = cdrecTmp;
return SS_COMP;
}
/***************************************************************************
* Function Name ReadTOC
*
*
***************************************************************************/
DWORD ReadTOC( HCDROM hCD, LPTOC toc )
{
DWORD dwStatus;
DWORD retVal = SS_COMP;
HANDLE heventSRB;
SRB_ExecSCSICmd s;
int idx = (int)hCD - 1;
if ( (idx<0) || (idx>=MAXCDHAND) )
{
alErrCode = ALERR_INVHANDLE;
return SS_ERR;
}
if ( WaitForSingleObject( cdMutexes[idx], TIMEOUT ) != WAIT_OBJECT_0 )
{
alErrCode = ALERR_LOCK;
return SS_ERR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -