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

📄 cdcache.c

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

    case 202:
      // no matches;
      break;

    case 403:
      // database entry corrupt
      break;

    case 409:
      // no handshake (probably won't happen with HTTP)
      break;
    }

  lpq->num = total;

  fclose( fp );
}


void GetLineFromBuf( char **src, char *tgt, int len )
{
  char *s, *t;

  if ( !src || !*src || !tgt )
    {
      return;
    }

  ZeroMemory( tgt, len );

  s = strstr( *src, "\r\n" );
  if ( !s )
    {
      *src += lstrlen( *src );
      return;
    }

  lstrcpyn( tgt, *src, len-1 );
  t = strstr( tgt, "\r\n" );
  if ( t && ((t - tgt) < len) )
    tgt[t-tgt] = '\0';
  
  *src = s + 2;
}


/*
 * extracts the category, cddbid and title(artist/album) from linebuf and 
 * stores it in lpq
 */
int extractCDDBQueryInfo( LPCDDBQUERYITEM lpq, char *linebuf )
{
  int i;
  char *p = linebuf;
  char *t;

  if ( !lpq || !linebuf || !*linebuf )
    return 0;

  ZeroMemory( lpq, sizeof(CDDBQUERY) );

  // extract the category
  i = 11;
  t = lpq->categ;
  while( *p && (*p != ' ') && i )
    {
      *t++ = *p++;
      i--;
    }
  if ( *p != ' ' )
    {
      return 0;
    }

  // extract the cddbid
  while ( *p && (*++p == ' ') );    // skip space
  i = 8;
  t = lpq->cddbId;
  while ( *p && ( isxdigit( *p ) ) && i )
    {
      *t++ = *p++;
      i--;
    }

  if ( *p != ' ' )
    {
      return 0;
    }

  // get artist and title
  while ( *p && (*++p == ' ') );    // skip space
  i = 80;
  t = lpq->artist;
  t[0] = '\0';
  while ( *p && (*p != '/') && i )
    {
      *t++ = *p++;
      i--;
    }
  i = lstrlen( lpq->artist );
  if ( i > 0 )
    {
      if ( lpq->artist[i-1] == ' ' )
	lpq->artist[i-1] = '\0';
    }

  if ( *p != '/' )
    {
      return 0;
    }

  while ( *p && (*++p == ' ') );    // skip space

  t = lpq->title;
  lstrcpyn( t, p, 80 );
  i = lstrlen( lpq->title );
  if ( i > 0 )
    {
      if ( lpq->title[i-1] == '\r' || lpq->title[i-1] == '\n' )
	lpq->title[i-1] = '\0';
    }


  return 1;
}


void SkipHTTPHeaders( char **buf )
{
  char *p;

  if ( !buf || !*buf || !**buf )
    return;

  p = *buf;

  if ( strncmp( p, "HTTP", 4 ) )
    {
      return;
    }

  p = strstr( p, "\r\n\r\n" );
  if ( p )
    {
      p += 4;
      *buf = p;
    }
}


/*
 * Returns the CDDB entry verbatim from the CDDB database.  If not large
 * enough, no data is copied.  Verifies that the return code from CDDB is
 * 210 -- CDDB entry follows...
 *
 * If the use of CDPLAYER.INI is enabled and the category is for the query
 * is "cdplayerini", then an attempt is made to read the information from
 * CDPLAYER.INI.
 */
DWORD CDDBGetDiskInfo( LPCDDBQUERYITEM lpq, char *szCDDBEntry, int maxLen )
{
  char *cmd, *p;
  char *retBuf;
  DWORD retVal = SS_ERR;

  if ( !lpq || !szCDDBEntry )
    return retVal;

  if ( !lstrcmp( lpq->categ, "cdplayerini" ) )
    return getDiskInfoCDPlayerIni( lpq, szCDDBEntry, maxLen );

  cmd = (char *)GlobalAlloc( GPTR, 512 );
  retBuf = (char *)GlobalAlloc( GPTR, maxLen );

  p = cmd;
  wsprintf( p, "cmd=cddb+read+%s+%s", lpq->categ, lpq->cddbId );
  p += lstrlen( p );
  wsprintf( p, "&hello=%s+%s&proto=3", szUser, szAgent );
  urlEncodeString( p );

      // send the query string
  if ( bUseProxy )
    CDDBPostCmdProxy( cmd, retBuf, maxLen );
  else
    CDDBPostCmd( cmd, retBuf, maxLen );

  // strip any HTTP headers
  p = retBuf;
  SkipHTTPHeaders( &p );

  if ( !strncmp( p, "210", 3 ) )
    {
      p = strstr( p, "\n" );
      if ( p )
	{
	  p += 1;  // skip the '\n'
	  if ( lstrlen(p) < maxLen )
	    {
	      strcpy( szCDDBEntry, p );
	      retVal = SS_COMP;
	      // should we add it to cdplayer.ini?
	      if ( bUseCDPlayerIni && *p )
		{
		  writeCDPlayerIniEntry( lpq, p );
		}
	    }
	}
    }

  GlobalFree( (HGLOBAL)cmd );
  GlobalFree( (HGLOBAL)retBuf );

  return retVal;
}



DWORD CDDBGetServerList( LPCDDBSITELIST lps )
{
  char *cmd, *p;
  char *retBuf;
  DWORD retVal = SS_ERR;

  if ( !lps || !lps->s )
    return retVal;

  cmd = (char *)GlobalAlloc( GPTR, 512 );
  retBuf = (char *)GlobalAlloc( GPTR, 4096 );

  p = cmd;
  wsprintf( p, "cmd=sites&hello=%s+%s&proto=3", szUser, szAgent );
  urlEncodeString( p );

  // send the query string
  if ( bUseProxy )
    CDDBPostCmdProxy( cmd, retBuf, 4096 );
  else
    CDDBPostCmd( cmd, retBuf, 4096 );

  if ( retBuf[0] )
    {
      // look for the "210 OK, site information..." message
      processSites( retBuf, lps );
      retVal = SS_COMP;
    }

  GlobalFree( (HGLOBAL)cmd );
  GlobalFree( (HGLOBAL)retBuf );

  return retVal;
}



void processSites( char *buf, LPCDDBSITELIST lps )
{
  char linebuf[81];
  char retCode[4] = "";
  char *p;
  int total, iRetCode;
  int maxLines = 100;

  // strip any HTTP headers
  p = buf;
  SkipHTTPHeaders( &p );

  GetLineFromBuf( &p, linebuf, 81 );

  strncpy( retCode, linebuf, 3 );
  iRetCode = atoi( retCode );

  total = 0;

  switch( iRetCode )
    {
    case 210:   // normal return code, site list follows
      while ( p && lps->num && (maxLines-- > 0) )
	{
	  GetLineFromBuf( &p, linebuf, 81 );
	  if ( !strcmp( linebuf, "." ) )
	    break;
	  if ( extractCDDBSiteInfo( &lps->s[total], linebuf ) )
	    {
	      total++;
	      lps->num--;
	    }
	}
      break;

    case 401: // no site info available
      break;
    }

  lps->num = total;
}



int extractCDDBSiteInfo( LPCDDBSITE lps, char *linebuf )
{
  char *p;
  char buf[6];

  if ( !lps || !linebuf || !*linebuf )
    return 0;

  ZeroMemory( lps, sizeof(CDDBSITE) );

  p = linebuf;

  // extract the server
  getWord( &p, lps->szServer, 81 );
  if ( *p != ' ' )
    return 0;

  // extract the protocol
  getWord( &p, buf, 6 );
  if ( *p != ' ' )
    return 0;
  if ( !lstrcmpi( buf, "http" ) )
    lps->bHTTP = TRUE;

  // extract the port number
  getWord( &p, buf, 6 );
  if ( *p != ' ' )
    return 0;
  lps->iPort = atoi( buf );
  if ( lps->bHTTP && !lps->iPort )
    lps->iPort = 80;

  // extract the CGI
  getWord( &p, lps->szCGI, 81 );
  if ( *p != ' ' )
    return 0;

  // extract north coordinate
  getWord( &p, lps->szNorth, 16 );
  if ( *p != ' ' )
    return 0;

  // extract north coordinate
  getWord( &p, lps->szSouth, 16 );
  if ( *p != ' ' )
    return 0;

  // extract the location
  while( *p && (*p == ' ') ) p++; 
  lstrcpyn( lps->szLocation, p, 80 );

  return -1;
}


void getWord( char **inBuf, char *outBuf, int len )
{
  char *p = *inBuf;

  ZeroMemory( outBuf, len );
  len--;

  // skip space
  while( *p && (*p == ' ') ) p++;

#if 0
  while( TRUE )
    {
      if ( !*p )
	break;
      if ( !isalnum( *p ) && (*p != '.') )
	break;
      if ( !len )
	break;
      *outBuf++ = *p++;
      len--;
    }
#else
  while( *p &&
	 ( isalnum( *p ) || ( *p == '.') || ( *p == '/' ) || ( *p == '~' ) ) &&
	 len )
    {
      *outBuf++ = *p++;
      len--;
    }
#endif

  *inBuf = p;
}


DWORD genCDPlayerIniIndex( HCDROM hCD )
{
  DWORD retVal = 0;
  BOOL bMSF;
  int idx = (int)hCD - 1;
  int i;
  TOC toc;
  DWORD dwAddr;

  bMSF = cdHandles[idx].bMSF;
  cdHandles[idx].bMSF = TRUE;

  memset( &toc, 0, sizeof(toc) );
  ReadTOC( hCD, &toc );

  for( i = 0; i <= (toc.lastTrack - toc.firstTrack); i++ )
    {
      MSB2DWORD( &dwAddr, toc.tracks[i].addr );
      retVal += dwAddr;
    }

  return retVal;
}


void MSB2DWORD( DWORD *d, BYTE *b )
{
  DWORD retVal;

  retVal = (DWORD)b[0];
  retVal = (retVal<<8) + (DWORD)b[1];
  retVal = (retVal<<8) + (DWORD)b[2];
  retVal = (retVal<<8) + (DWORD)b[3];

  *d = retVal;
}


DWORD getDiskInfoCDPlayerIni( LPCDDBQUERYITEM lpq, char *szCDDBEntry, int maxLen )
{
  UINT i, numRead;
  char buf[256];
  char idx[5];
  char defaultName[13];
  char *p;

  if ( !lpq || !szCDDBEntry )
    return SS_ERR;

  numRead = GetPrivateProfileInt( lpq->cddbId, "NUMTRACKS", 0, szCDPlayerIni );
  if ( numRead )
    {
      lstrcpy( lpq->categ, "rock" );
      lpq->bExact = TRUE;
      GetPrivateProfileString( lpq->cddbId, "ARTIST", "", buf, 256, szCDPlayerIni );
      lstrcpyn( lpq->artist, buf, 80 ); lpq->artist[80] = '\0';
      GetPrivateProfileString( lpq->cddbId, "TITLE", "", buf, 256, szCDPlayerIni );
      lstrcpyn( lpq->title, buf, 80 ); lpq->title[80] = '\0';
      p = szCDDBEntry;
      wsprintf( buf, "DTITLE=%s / %s\r\n", lpq->artist, lpq->title );
      if ( maxLen > lstrlen(buf) )
	{
	  lstrcpy( p, buf );
	  p += lstrlen( buf );
	  maxLen -= lstrlen( buf );
	}
      for( i = 0; i < numRead; i++ )
	{
	  wsprintf( idx, "%d", i );
	  wsprintf( defaultName, "Track %d", i+1 );
	  GetPrivateProfileString( lpq->cddbId, idx, defaultName, buf, 256, szCDPlayerIni );
	  if ( maxLen > (lstrlen( buf )+12) )
	    {
	      wsprintf( p, "TTITLE%d=%s\r\n", i, buf );
	      maxLen -= lstrlen( p );
	      p += lstrlen( p );
	    }
	  else
	    break;
	}
    }

  if ( numRead )
    return SS_COMP;
  return SS_ERR;
}


BOOL isCDinCDPlayerIni( char *s )
{
  UINT uiVal;

  uiVal = GetPrivateProfileInt( s, "NUMTRACKS", 0, "cdplayer.ini" );

  return (BOOL)uiVal;
}


void addCDPlayerCDDBIndex( DWORD cdpIdx, DWORD cddbId, DWORD numTracks )
{
  if ( iNextIndex == -1 )
    ZeroMemory( dwCDDB2CDPlayer, sizeof(dwCDDB2CDPlayer) );

  if ( (++iNextIndex % 20) == 0 )
    iNextIndex = 0;

  dwCDDB2CDPlayer[iNextIndex][0] = cdpIdx;        // cdplayer.ini index
  dwCDDB2CDPlayer[iNextIndex][1] = cddbId;        // cddb id
  dwCDDB2CDPlayer[iNextIndex][2] = numTracks;     // number of tracks
}


DWORD CDDBIndex2CDPlayerIni( char *szCDDBId, DWORD *dwRetVal, DWORD *numTracks )
{
  int i;
  DWORD dwIdx = (DWORD)strtoul( szCDDBId, NULL, 16 );

  for( i = 0; i < 20; i++ )
    {
      if ( dwCDDB2CDPlayer[i][1] == dwIdx )
	{
	  *dwRetVal = dwCDDB2CDPlayer[i][0];
	  *numTracks = dwCDDB2CDPlayer[i][2];
	  return *dwRetVal;
	}
    }

  return 0;
}


/*
 * Stores a CDDB entry in cdplayer.ini.  NOTE: the buffer pointed to
 * by szCDDBEntry may be modified by this function.  Do not count on the
 * buffer being unmodified!!!
 */
void writeCDPlayerIniEntry( LPCDDBQUERYITEM lpq, char *szCDDBEntry )
{
  DWORD dwCDPlayerIdx, dwNumTracks;
  char section[24];
  char buf[128];
  char *p1, *p2;

  CDDBIndex2CDPlayerIni( lpq->cddbId, &dwCDPlayerIdx, &dwNumTracks );
  if ( !dwCDPlayerIdx )
    {
      return;
    }

  wsprintf( section, "%X", dwCDPlayerIdx );
  WritePrivateProfileString( section, "EntryType", "1", szCDPlayerIni );
  WritePrivateProfileString( section, "artist", lpq->artist, szCDPlayerIni );
  WritePrivateProfileString( section, "title", lpq->title, szCDPlayerIni );
  WritePrivateProfileString( section, "genre", lpq->categ, szCDPlayerIni );
  wsprintf( buf, "%d", dwNumTracks );
  WritePrivateProfileString( section, "numtracks", buf, szCDPlayerIni );

  while (*szCDDBEntry)
    {
      GetLineFromBuf( &szCDDBEntry, buf, 128 );
      if ( !szCDDBEntry )
	break;
      if ( !strncmp( "TTITLE", buf, 6 ) )
	{
	  p1 = buf + 6;
	  p2 = strstr( buf, "=" );
	  if ( *p1 && p2 )
	    {
	      *p2 = '\0';
	      p2++;
	      WritePrivateProfileString( section, p1, p2, szCDPlayerIni );
	    }
	}
    }
}

⌨️ 快捷键说明

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