如何使用WinAPI识别CD-ROM驱动器中的光盘类型?

时间:2014-04-11 11:45:26

标签: c winapi cd-rom

我正在编写一个可以与音频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为所有被识别为音频的光盘分配名称“Audio CD”的事实。这感觉不对,并且在混合模式CD上会失败,因为它们在Windows中的名称由数据轨道的卷名决定。另外,else阻止就在这里,因为我注意到当驱动器中没有光盘时GetVolumeInformation会返回GetLastError等于ERROR_INVALID_PARAMETER的错误。< / p>

理想情况下,我正在寻找像Linux上的CDROM_DISC_STATUS ioctl这样的东西。它会返回CDS_NO_INFOCDS_AUDIOCDS_MIXED或其他一些值,具体取决于光盘的内容。

还有其他办法吗?那么混合模式光盘呢?

2 个答案:

答案 0 :(得分:3)

您可以使用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,我确定应该有一个IOCTL提供必要的信息。

答案 1 :(得分:0)

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

CD配置文件是:

0x0008 CD-ROM
0x0009 CD-R
0x000A CD-RW
0x0020双密度CD-ROM
0x0021双密度CD-R
0x0022双密度CD-RW