用于读取原始CD-ROM数据的Windows IOCTL不返回纠错数据

时间:2018-04-22 15:47:50

标签: windows winapi driver ioctl cd-rom

我正在尝试制作一个程序,从CD(数据和音频)开始从各种类型的光盘中提取原始扇区数据。

这没什么特别的,这个概念本身很好,可以在Linux上使用类似的IOCTL。

我在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扇区视图之间的并排比较: enter image description here

对于今后来到这里的任何人来说,下一个最好的方法就是使用SPTI,如下所述:How to issue a READ CD command to a CD-ROM drive in Windows?。我不想考虑为什么Windows IOCTL无法正常工作(省略EDC)的答案!

0 个答案:

没有答案