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

📄 aspilib.c

📁 读取音乐光盘磁道为磁盘文件的DLL源码
💻 C
📖 第 1 页 / 共 3 页
字号:

  if ( !cdHandles[idx].used )
    {
      alErrCode = ALERR_INVHANDLE;
      ReleaseMutex( cdMutexes[idx] );
      return SS_ERR;
    }

  heventSRB = CreateEvent( NULL, TRUE, FALSE, NULL );

  memset( &s, 0, sizeof( s ) );
  s.SRB_Cmd        = SC_EXEC_SCSI_CMD;
  s.SRB_HaID       = cdHandles[idx].ha;
  s.SRB_Target     = cdHandles[idx].tgt;
  s.SRB_Lun        = cdHandles[idx].lun;
  s.SRB_Flags      = SRB_DIR_IN | SRB_EVENT_NOTIFY;
  s.SRB_BufLen     = 0x324;
  s.SRB_BufPointer = (BYTE FAR *)toc;
  s.SRB_SenseLen   = 0x0E;
  s.SRB_CDBLen     = 0x0A;
  s.SRB_PostProc   = (LPVOID)heventSRB;
  s.CDBByte[0]     = 0x43;
  s.CDBByte[1]     = cdHandles[idx].bMSF?0x02:0x00;
  //  s.CDBByte[1] = 0x02;               /* 0x02 == MSF format, 0x00 == LBA */
  s.CDBByte[7]     = 0x03;               /* length of buffer to hold TOC    */
  s.CDBByte[8]     = 0x24;               /*      == 0x324                   */

  ResetEvent( heventSRB );
  dwStatus = pfnSendASPI32Command( (LPSRB)&s );

  if ( dwStatus == SS_PENDING )
    {
      WaitForSingleObject( heventSRB, 4000 );
    }
  CloseHandle( heventSRB );

  if ( s.SRB_Status != SS_COMP )
    {
      alErrCode = ALERR_ASPI;
      alAspiErr = s.SRB_Status;
      retVal = SS_ERR;
    }

#ifdef _DEBUG
  {
    FILE *fp = fopen( "toc.dat", "wb" );
    fwrite( toc, 1, sizeof(TOC), fp );
    fclose( fp );
  }
#endif

  ReleaseMutex( cdMutexes[idx] );
  return retVal;
}


/***************************************************************************
 * resetSCSIBus
 * 
 * According to Adaptec, this command can cause problems in Win95
 *
 ***************************************************************************/
void resetSCSIBus( void )
{
  DWORD dwStatus;
  HANDLE heventSRB;
  SRB_BusDeviceReset s;

  dbprintf( "akrip32: reset bus!" );
  heventSRB = CreateEvent( NULL, TRUE, FALSE, NULL );

  memset( &s, 0, sizeof( s ) );
  s.SRB_Cmd = SC_RESET_DEV;
  s.SRB_PostProc = (LPVOID)heventSRB;

  ResetEvent( heventSRB );
  dwStatus = pfnSendASPI32Command( (LPSRB)&s );
  if ( dwStatus == SS_PENDING )
    {
      WaitForSingleObject( heventSRB, DEFWAITLEN );
    }
  CloseHandle( heventSRB );

#ifdef _DEBUG
  if ( s.SRB_Status != SS_COMP )
    {
      dbprintf( "akrip32: RESET BUS aspi status: 0x%08X\n", s.SRB_Status );
    }
#endif
}


/******************************************************************
 * GetCDList
 *
 * Scans all host adapters for CD-ROM units, and stores information
 * for all units located
 ******************************************************************/
int GetCDList( LPCDLIST cd )
{
  SRB_HAInquiry sh;
  SRB_GDEVBlock sd;
  int numAdapters, i, j, k;
  int maxTgt;

  /* initialize cd list */
  maxTgt = cd->max;
  memset( cd, 0, sizeof(*cd) );
  cd->max = maxTgt;

  numAdapters = GetNumAdapters();
#ifdef _DEBUG
  dbprintf( "AKRip32: GetCDList(): numAdapters == %d", numAdapters );
#endif
  //return 0;

  for( i = 0; i < numAdapters; i++ )
    {
      memset( &sh, 0, sizeof( sh ) );
      sh.SRB_Cmd   = SC_HA_INQUIRY;
      sh.SRB_HaID  = i;
      pfnSendASPI32Command( (LPSRB)&sh );

      /* on error skip to next adapter */
      if ( sh.SRB_Status != SS_COMP )
	continue;

      maxTgt = (int)sh.HA_Unique[3];

      if ( maxTgt == 0 )
	maxTgt = 8;

      for( j = 0; j < maxTgt; j++ )
	{
	  for( k = 0; k < 8; k++ )
	    {
	      memset( &sd, 0, sizeof( sd ) );
	      sd.SRB_Cmd   = SC_GET_DEV_TYPE;
	      sd.SRB_HaID  = i;
	      sd.SRB_Target = j;
	      sd.SRB_Lun   = k;
	      pfnSendASPI32Command( (LPSRB)&sd );
	      if ( sd.SRB_Status == SS_COMP )
		{
		  if ( sd.SRB_DeviceType == DTYPE_CDROM )
		    {
		      cd->cd[cd->num].ha = i;
		      cd->cd[cd->num].tgt = j;
		      cd->cd[cd->num].lun = k;
		      memset( cd->cd[cd->num].id, 0, MAXIDLEN+1 );
		      GetDriveInfo( i, j, k, &(cd->cd[cd->num]) );
		      // getDriveInfo( i, j, k, cd->cd[cd->num].id, MAXIDLEN+1 );
		      cd->num++;
		    }
#ifdef _DEBUG
		  else
		    {
		      dbprintf( "       : sd.SRB_DeviceType == %d", sd.SRB_DeviceType );
		      GetDriveInfo( i, j, k, NULL );
		    }
#endif
		}
	    }
	}
    }

  return 1;
}


DWORD ReadCDAudioLBA( HCDROM hCD, LPTRACKBUF t )
{
  int idx = (int)hCD - 1;
  DWORD retVal;

  if ( (idx<0) || (idx>=MAXCDHAND) )
    {
      alErrCode = ALERR_INVHANDLE;
      return SS_ERR;
    }

  retVal = WaitForSingleObject( cdMutexes[idx], TIMEOUT );
  if ( retVal != WAIT_OBJECT_0 )
    {
      alErrCode = ALERR_LOCK;
      return SS_ERR;
    }

  if ( !cdHandles[idx].used )
    {
      alErrCode = ALERR_INVHANDLE;
      ReleaseMutex( cdMutexes[idx] );
      return SS_ERR;
    }

  retVal = cdHandles[idx].pfnRead( hCD, t );
  ReleaseMutex( cdMutexes[idx] );

  return retVal;
}


/*
 * Test the currently set read function.  Fills the buffer with 0xAA
 * prior to reading, and then checks the read area for a series of 0xAA
 * bytes.  This is because some read commands do not return an error, but
 * also don't read correct data or a full buffer.
 */
DWORD testReadCDAudio( HCDROM hCD, LPTRACKBUF t )
{
  DWORD i;
  DWORD dwStatus;
  BYTE *p;
  int idx = (int)hCD - 1;
  int count;

  // fill buffer with dummy data
  memset( t->buf, 0xAA, t->len );

  dwStatus = cdHandles[idx].pfnRead( hCD, t );
  if ( dwStatus != SS_COMP )
    {
      return dwStatus;
    }

  p = &(t->buf[t->startOffset]);
  for( i = 0, count = 0; i < t->len; i += 4 )
    {
      if ( *((DWORD *)p) == 0xAAAAAAAA )
	count += 1;
      else
	count = 0;
      if ( count == 8 )
	{
	  return SS_ERR;
	}

      p += 4;
    }

  return dwStatus;
}


/***************************************************************************
 * readCDAudioLBA_ANY
 *
 * Attempts to autodetect the proper read function for the CD.  It tries
 * ATAPI2, ATAPI1, and then finally READ10
 *
 ***************************************************************************/
DWORD readCDAudioLBA_ANY( HCDROM hCD, LPTRACKBUF t )
{
  DWORD dwStatus;
  int idx = (int)hCD - 1;
  int i, j;
  int ord[7] = { 2, 1, 8, 4, 5, 6, 7 };

  if ( (idx<0) || (idx>=MAXCDHAND) || !cdHandles[idx].used )
    {
      alErrCode = ALERR_INVHANDLE;
      return SS_ERR;
    }

  if ( t->numFrames * 2352 > t->maxLen )
    {
      alErrCode = ALERR_BUFTOOSMALL;
      return SS_ERR;
    }

  for( i = 0; i < 7; i++ )
    {
#ifdef _DEBUG
      dbprintf( "akrip32: testing read fn %d", ord[i] );
#endif

      cdHandles[idx].readType = ord[i];
      cdHandles[idx].pfnRead = aReadFn[ord[i]];
      cdHandles[idx].pfnDeinit = NULL;
      cdHandles[idx].bInit = FALSE;

      for( j = 0; j < 3; j++ )
	{
	  dwStatus = testReadCDAudio( hCD, t );
	  if ( dwStatus == SS_COMP )
	    {
	      return dwStatus;
	    }
	}
    }


  // Failed to find compatible read mode, so we reset to the default
  // and return the error
  cdHandles[idx].readType = CDR_ANY;
  cdHandles[idx].pfnRead  = readCDAudioLBA_ANY;
  return dwStatus;
}


DWORD GetASPI32SupportInfo( void )
{
  return pfnGetASPI32SupportInfo();
}


DWORD SendASPI32Command( LPSRB s )
{
  return pfnSendASPI32Command( s );
}


#define _GEN_CDPARMS 0
DWORD readCDParameters( HCDROM hCD, BOOL bChangeMask )
{
  HANDLE h;
  SRB_ExecSCSICmd s;
  DWORD d;
  BYTE b[256];
  int lenData;
  BYTE *p;
  BYTE *pMax = b + 256;
  LPSENSEMASK psm;
  int idx = (int)hCD - 1;

#if _GEN_CDPARMS
  FILE *fp;
#endif

  if ( (idx<0) || (idx>=MAXCDHAND) || !cdHandles[idx].used )
    {
      alErrCode = ALERR_INVHANDLE;
      return SS_ERR;
    }

  cdHandles[idx].smRead = FALSE;
  psm = &cdHandles[idx].sm;
  memset( psm, 0, sizeof( SENSEMASK ) );


  h = CreateEvent( NULL, TRUE, FALSE, NULL );
  memset( &s, 0, sizeof( s ) );
  memset( b, 0xFF, 256 );
  s.SRB_Cmd      = SC_EXEC_SCSI_CMD;
  s.SRB_HaID     = cdHandles[idx].ha;
  s.SRB_Target   = cdHandles[idx].tgt;
  s.SRB_Lun      = cdHandles[idx].lun;
  s.SRB_Flags    = SRB_DIR_IN | SRB_EVENT_NOTIFY;
  s.SRB_BufLen   = 256;
  s.SRB_BufPointer = b;
  s.SRB_CDBLen   = 12;
  s.SRB_PostProc = (LPVOID)h;
  s.CDBByte[0]   = 0x5A;
  s.CDBByte[2]   = 0x3F;
  s.CDBByte[7]   = 0x01;
  s.CDBByte[8]   = 0x00;

  /* do we want just a mask of changable items? */
  if ( bChangeMask )
    s.CDBByte[2] |= 0x40;

  ResetEvent( h );
  d = pfnSendASPI32Command( (LPSRB)&s );
  if ( d == SS_PENDING )
    {
      WaitForSingleObject( h, 500 );
    }
  CloseHandle( h );

  if ( s.SRB_Status != SS_COMP )
    {
      alErrCode = ALERR_ASPI;
      alAspiErr = s.SRB_Status;
      ReleaseMutex( cdMutexes[idx] );
      return SS_ERR;
    }

#if _GEN_CDPARMS
  fp = fopen( "cdparms.dat", "wb" );
  if ( fp )
    {
      fwrite( b, 1, 256, fp );
      fclose( fp );
    }
#endif

  lenData = ((unsigned int)b[0] << 8) + b[1];

  /* set to first sense mask, and then walk through the masks */
  p = b + 8;
  while( (p < &(b[2+lenData])) && (p < pMax) )
    {
      BYTE which;

      which = p[0] & 0x3F;
      switch( which )
	{
	case READERRREC:
	  psm->rerAvail = TRUE;
	  memcpy( psm->rer, p, p[1]+2 );
	  break;
	case CDRPARMS:
	  psm->cpmAvail = TRUE;
	  memcpy( psm->cpm, p, p[1]+2 );
	  break;
	case CDRAUDIOCTL:
	  psm->cacmAvail = TRUE;
	  memcpy( psm->cacm, p, p[1]+2 );
	  break;
	case CDRCAPS:
	  psm->ccsmAvail = TRUE;
	  memcpy( psm->ccsm, p, p[1]+2 );
	  break;
	}
      p += (p[1] + 2);
    }

  cdHandles[idx].smRead = TRUE;
  return s.SRB_Status;
}


/****************************************************************
 * Generic function to query CD unit capabilities and parameters
 *
 * which:   specifies the parm we wish to query
 * pNum:    pointer to DWORD to return data
 *
 * returns: If the parm is not available, returns FALSE.  Otherwise
 *          returns TRUE.
 *
 * The data requested will either be returned as a BOOL, or copied
 * to pNum, depending on the parameter requested.
 ****************************************************************/
BOOL QueryCDParms( HCDROM hCD, int which, DWORD *pNum )
{
  BOOL retVal = FALSE;
  DWORD dwTmp;
  int idx = (int)hCD - 1;

  if ( (idx<0) || (idx>=MAXCDHAND) || !cdHandles[idx].used )
    {
      alErrCode = ALERR_INVHANDLE;
      return FALSE;
    }

  if ( WaitForSingleObject( cdMutexes[idx], TIMEOUT ) != WAIT_OBJECT_0 )
    {
      alErrCode = ALERR_LOCK;
      return SS_ERR;
    }

  if ( pNum )
    *pNum = 0;
  else
    pNum = &dwTmp;

  if ( !cdHandles[idx].smRead )
    {
      if ( readCDParameters( hCD, FALSE ) != SS_COMP )
	{
	  ReleaseMutex( cdMutexes[idx] );
	  return FALSE;
	}
    }

  switch( which )
    {
    case CDP_READCDR:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[2] & 0x01);
      break;

    case CDP_READCDE:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[2] & 0x02);
      break;

    case CDP_METHOD2:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[2] & 0x04);
      break;

    case CDP_WRITECDR:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[3] & 0x01);
      break;

    case CDP_WRITECDE:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[3] & 0x02);
      break;

    case CDP_AUDIOPLAY:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[4] & 0x01);
      break;

    case CDP_COMPOSITE:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[4] & 0x02);
      break;

    case CDP_DIGITAL1:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[4] & 0x04);
      break;

    case CDP_DIGITAL2:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[4] & 0x08);
      break;

    case CDP_M2FORM1:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[4] & 0x10);
      break;

    case CDP_M2FORM2:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[4] & 0x20);
      break;

    case CDP_MULTISES:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[4] & 0x40);
      break;

    case CDP_CDDA:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[5] & 0x01);
      break;

    case CDP_RW:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[5] & 0x04);
      break;

    case CDP_RWCORR:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[5] & 0x08);
      break;

    case CDP_C2SUPP:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[5] & 0x10);
      break;

    case CDP_ISRC:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[5] & 0x20);
      break;

    case CDP_UPC:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[5] & 0x40);
      break;

    case CDP_CANLOCK:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[6] & 0x01);
      break;

    case CDP_LOCKED:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[6] & 0x02);
      break;

    case CDP_PREVJUMP:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[6] & 0x04);
      break;

    case CDP_CANEJECT:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[6] & 0x08);
      break;

    case CDP_SEPVOL:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[7] & 0x01);
      break;

    case CDP_SEPMUTE:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[7] & 0x02);
      break;

    case CDP_SDP:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[7] & 0x04);
      break;

    case CDP_SSS:
      retVal = cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[7] & 0x08);
      break;

    case CDP_MECHTYPE:
      if ( cdHandles[idx].sm.ccsmAvail )
	{
	  retVal = TRUE;
	  *pNum = (DWORD)(cdHandles[idx].sm.ccsm[6] >> 5);
	}
      break;

    case CDP_STREAMACC:
      return cdHandles[idx].sm.ccsmAvail && (cdHandles[idx].sm.ccsm[5] & 0x02);
      break;

    case CDP_MAXSPEED:
      if ( cdHandles[idx].sm.ccsmAvail )
	{
	  retVal = TRUE;
	  *pNum = ((DWORD)cdHandles[idx].sm.ccsm[8] << 8) + (DWORD)cdHandles[idx].sm.ccsm[9];
	}
      break;

    case CDP_NUMVOL:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -