2

我正在尝试制作一个程序,从各种类型的光盘中提取原始扇区数据,从 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;
}

输出和 IsoBuster 行业视图之间的并排比较: 在此处输入图像描述

仅供将来来到这里的任何人参考,让它工作的下一个最好的方法肯定是使用此处描述的 SPTI:如何在 Windows 中向 CD-ROM 驱动器发出 READ CD 命令?. 我不想考虑为什么 Windows IOCTL 不起作用的答案(省略 EDC)!

4

0 回答 0