⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aspilib.c

📁 读取音乐光盘磁道为磁盘文件的DLL源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * 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 + -