我正在编写一个将与音频CD和混合CD一起使用的应用程序。我想要一种确定应用程序使用的驱动器中当前是否存在音频或混合类型(至少有一个音轨)光盘的方法。

到目前为止,我可以通过GetDriveType识别出该驱动器是CD-ROM。但是,事实证明,识别驱动器中实际存在的介质并不那么容易。到目前为止,这是我得到的:

int drive_has_audio_disc(const char *root_path)
{
  char volume_name[MAX_PATH+1];
  BOOL winapi_rv;
  DWORD fs_flags;
  int rv;

  winapi_rv = GetVolumeInformation(root_path, volume_name, sizeof(volume_name),
    NULL, NULL, &fs_flags, NULL, 0);
  if(winapi_rv != 0)
  {
    rv = (strcmp(volume_name, "Audio CD") == 0 &&
      (fs_flags & FILE_READ_ONLY_VOLUME));
  }
  else
  {
    rv = (GetLastError() == ERROR_INVALID_PARAMETER) ? 0 : -1;
  }
  return rv;
}

但是,它依赖于Windows将名称“音频CD”分配给所有被识别为音频的光盘这一事实。这感觉不对,并且在混合模式CD上将失败,因为在Windows中它们的名称由数据轨道的卷名称决定。另外,else块在这里,因为我注意到驱动器中没有光盘时,GetVolumeInformation返回的错误是GetLastError等于ERROR_INVALID_PARAMETER

理想情况下,我正在寻找Linux上的CDROM_DISC_STATUS ioctl之类的东西。根据光盘的内容,它返回CDS_NO_INFOCDS_AUDIOCDS_MIXED或其他一些值。

还有其他处理方式吗?那混合模式光盘呢?

最佳答案

您可以使用CD-ROM I/O Control Codes,尤其是 IOCTL_CDROM_READ_TOC 。它返回的结构如下所示:

struct TRACK_DATA {
  UCHAR Reserved;
  UCHAR Control  :4;
  UCHAR Adr  :4;
  UCHAR TrackNumber;
  UCHAR Reserved1;
  UCHAR Address[4];
}

struct CDROM_TOC {
  UCHAR      Length[2];
  UCHAR      FirstTrack;
  UCHAR      LastTrack;
  TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS];
};

您可以找到有关如何检索它的示例on Larry Osterman's blog
由此您应该能够确定确切的光盘类型。如果没有,请查看其他IOCTL,我确定应该有一个为您提供必要的信息。

10-07 12:16