我正在尝试制作一个程序,从各种类型的光盘中提取原始扇区数据,从 CD(数据和音频)开始。
这没什么特别的,这个概念本身很好,并且可以在具有类似 IOCTL 的 Linux 上运行。
我在 Windows 上遇到的问题是 ECC/EDC 数据不正确(基本上归零)。您可以通过将命令返回的内容与 IsoBuster 或 ImgBurn 等其他程序输出(或在 Linux 上使用等效命令)进行比较来了解这一点。
这些数据是否会因某种原因受到 Windows 安全策略的影响?还是驱动程序错误?
请注意,我在 Windows 10 上看到了这种情况。以管理员身份运行时,我得到了相同的结果。
要清楚哪些数据受到影响,请参阅此处的漂亮表格: https ://en.wikipedia.org/wiki/CD-ROM#CD-ROM_format 。在普通数据 CD(模式 1)上,它是 2352 扇区的最后 288 个字节。
演示问题的代码:
#include <windows.h>
#include <winioctl.h> // From the Win32 SDK \Mstools\Include
#include "ntddcdrm.h" // From the Windows NT DDK \Ddk\Src\Storage\Inc
int main()
{
HANDLE hCD = CreateFile(L"\\\\.\\D:", GENERIC_READ,
FILE_SHARE_READ,
0, OPEN_EXISTING, 0,
0);
//the sector to read
int lba = 0;
RAW_READ_INFO rawReadInfo;
rawReadInfo.DiskOffset.QuadPart = (long long)lba * 2048;
rawReadInfo.SectorCount = 1;
rawReadInfo.TrackMode = RawWithC2AndSubCode;
DWORD x_size;
char* buf = (char*)malloc(CD_RAW_SECTOR_WITH_C2_AND_SUBCODE_SIZE);
int rc = DeviceIoControl(hCD, IOCTL_CDROM_RAW_READ,
&rawReadInfo, sizeof(rawReadInfo),
buf, CD_RAW_SECTOR_WITH_C2_AND_SUBCODE_SIZE,
&x_size, NULL);
printf("rc: %d\n", rc);
printf("x_size: %d\n", x_size);
int i;
printf("\nSync, Addr, Mode (16 bytes)\n");
for (i = 0; i < 16; i++) {
printf("%hhX", buf[i]); //this data comes back fine
}
printf("\nData (2048 bytes)\n");
for (i = 16; i < 16+2048; i++) {
printf("%hhX", buf[i]); //this data comes back fine
}
printf("\nED, RZ, EC (288 bytes)\n");
for (i = 16 + 2048; i < 16 + 2048 + 288; i++) {
printf("%hhX", buf[i]); //this data comes back wrong
}
printf("\nC2, Sub (392 bytes)\n");
for (i = 16 + 2048 + 288; i < 2744; i++) {
printf("%hhX", buf[i]); //not sure if this is right or not
}
//dumb code to block terminal from closing
char str[80];
fgets(str, 10, stdin);
return 0;
}
仅供将来来到这里的任何人参考,让它工作的下一个最好的方法肯定是使用此处描述的 SPTI:如何在 Windows 中向 CD-ROM 驱动器发出 READ CD 命令?. 我不想考虑为什么 Windows IOCTL 不起作用的答案(省略 EDC)!