winapi - Windows IOCTL til læsning af rå cd-rom-data, der ikke returnerer fejlkorrigeringsdata

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg forsøger at lave et program, der uddrager rå sektordata fra optiske diske af forskellige typer, begyndende med cd'er (data og lyd).


Dette er ikke noget særligt, og selve konceptet er fint og arbejder på Linux med lignende IOCTL'er.


Det problem, jeg bare har på Windows, er, at ECC/EDC-dataene ikke er korrekte (i princippet nulstillet). Du kan se dette ved at sammenligne, hvad kommandoen vender tilbage med andre programmer, som outputs som IsoBuster eller ImgBurn (eller ved brug af tilsvarende kommandoer på Linux).


Er disse data noget, som Windows-sikkerhedspolitikken påvirker af en eller anden grund? Eller en driverfejl?


Bemærk, at jeg ser dette ske på Windows 10. Jeg får det samme resultat, når jeg kører som administrator.


For at være klar over, hvilke data der er berørt, se det nice bord her:
https://en.wikipedia.org/wiki/CD-ROM#CD-ROM\_format. På en normal data-cd (tilstand 1) er det de sidste 288 byte af en 2352 sektor. [2]


Kode til at demonstrere problemet:


#include <windows.h>
#include <winioctl.h>  // From the Win32 SDK MstoolsInclude
#include "ntddcdrm.h"  // From the Windows NT DDK DdkSrcStorageInc


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
", rc);
    printf("x\_size: \%d
", x\_size);

    int i;
    printf("
Sync, Addr, Mode (16 bytes)
");
    for (i = 0; i < 16; i++) {
        printf("\%hhX", buf[i]); //this data comes back fine
    }
    printf("
Data (2048 bytes)
");
    for (i = 16; i < 16+2048; i++) {
        printf("\%hhX", buf[i]); //this data comes back fine
    }
    printf("
ED, RZ, EC (288 bytes)
");
    for (i = 16 + 2048; i < 16 + 2048 + 288; i++) {
        printf("\%hhX", buf[i]); //this data comes back wrong
    }
    printf("
C2, Sub (392 bytes)
");
    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;
}


Side ved side sammenligning mellem output og IsoBuster sektor visning:
Indtast billedbeskrivelse her [3]


FYI for alle, der kommer her i fremtiden, er det næste bedste at få det til at arbejde, at bruge SPTI som beskrevet her: Sådan udgives en READ CD-kommando til et cd-rom-drev i Windows ?. Jeg vil ikke overveje at et svar på, hvorfor Windows IOCTL ikke virker, men (udelader EDC)!

Bedste reference