5

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

到目前为止,我能够通过GetDriveType. 然而,事实证明,识别实际在驱动器内的媒体并不是那么容易。这是我到目前为止所得到的:

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驱动器中根本没有光盘。

理想情况下,我正在寻找类似于CDROM_DISC_STATUSLinux 上的 ioctl 的东西。它根据光盘的内容返回CDS_NO_INFOCDS_AUDIO、或其他一些值。CDS_MIXED

有没有其他方法来处理这个?那么混合模式光盘呢?

4

2 回答 2

3

您可以使用CD-ROM I/O 控制代码,尤其是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];
};

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

于 2014-04-11T13:36:55.210 回答
0

我曾经不得不为一个项目做类似的事情,但用的是 DVD。您可以使用DeviceIoControl(IOCTL_SCSI_PASS_THROUGH)多媒体命令 (MMC) GET CONFIGURATION命令直接发送到驱动器以检索其当前活动的配置文件,该配置文件基于当前加载的特定类型的光盘。

CD 配置文件是:

0x0008CD-ROM
0x0009CD-R
0x000ACD-RW
0x0020双倍密度 CD-ROM
0x0021双倍密度 CD-R
0x0022双倍密度 CD-RW

于 2014-04-12T00:56:13.727 回答