我正在编写一个可以与音频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.
理想情况下,我正在寻找类似Linux上的CDROM_DISC_STATUS ioctl.它将返回CDS_NO_INFO,CDS_AUDIO,CDS_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,我确信应该有一个IOCTL给你必要的信息.