⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvdioctl.cpp

📁 WinCE5.0BSP for Renesas SH7770
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        "Atapi!CSHXDiskAndCD::DVDGetRegion> %u user-controlled changes available\r\n" \
        ), x.ResetCounts & 0x07)); \
    DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (_T( \
        "Atapi!CSHXDiskAndCD::DVDGetRegion> Region mask=%u\r\n" \
        ), x.SystemRegion ^ 0xFF)); \
    DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (_T( \
        "Atapi!CSHXDiskAndCD::DVDGetRegion> RPC Scheme=%u\r\n" \
        ), x.RPCVer));
#else
#define DUMP_REPORT_KEY(x)
#endif

DWORD
CSHXDiskAndCD::DVDGetRegion(
    PIOREQ pIOReq
    )
{
    DWORD                dwError = ERROR_SUCCESS;
    DWORD                dwLength;
    SGX_BUF              SgBuf;
    DWORD                dwRet;
    RKFMT_RPC            rpcData;
    PDVD_REGIONCE        preg;
    ATAPI_COMMAND_PACKET CmdPkt;

    memset(&CmdPkt, 0, sizeof(ATAPI_COMMAND_PACKET));

    // map address and check for security violation
    preg = (PDVD_REGIONCE)MapCallerPtr((LPVOID)pIOReq->pOutBuf, sizeof(BYTE));
    if (pIOReq->pOutBuf != NULL && preg == NULL) {
        // security violation
        DEBUGMSG(ZONE_ERROR, (TEXT(
            "Atapi!CSHXDiskAndCD::DVDGetRegion> Failed to map pointer to caller\r\n"
            )));
        return ERROR_INVALID_PARAMETER;
    }

    // read disc copy system and region
    DVDGetCopySystem(&(preg->CopySystem), &(preg->RegionData));

    memset(&CmdPkt, 0, sizeof(ATAPI_COMMAND_PACKET));

    // create command packet to read RPC setting (report key)
    dwLength = DVDSetupReadTitleKey(&CmdPkt, DvdGetRPC, 0, 0);
    SgBuf.sb_len = sizeof(RKFMT_RPC);
    SgBuf.sb_buf = (PBYTE) &rpcData;

    // send command
    if (AtapiSendCommand(&CmdPkt)) {
        // fetch result
        if (AtapiReceiveData(&SgBuf, 1, &dwRet)) {
            DUMP_REPORT_KEY(rpcData);
            // is the drive in a non-NONE RPC state?
            if (rpcData.ResetCounts & 0xc0) {
                // the drive is in SET, LAST CHANCE or PERM, i.e., this drive
                // has had its region set already
                preg->SystemRegion = rpcData.SystemRegion ^ 0xFF;
                preg->ResetCount = rpcData.ResetCounts & 0x07;
            }
            else {
                // the drive is in NONE, i.e., this drive is a virgin
                DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (_T(
                    "Atapi!CSHXDiskAndCD::DVDGetRegion> Region has never been set\r\n"
                    )));
                preg->SystemRegion = 0xFF;
                preg->ResetCount = 5;
            }
        }
        else {
            DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (TEXT(
                "Atapi!CSHXDiskAndCD::DVDGetRegion> Failed to receive REPORT KEY response\r\n"
                )));
            dwError = ERROR_READ_FAULT;
        }
    }
    else {
        DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (TEXT(
            "Atapi!CSHXDiskAndCD::DVDGetRegion> Failed to send REPORT KEY command\r\n"
            )));
        dwError = ERROR_READ_FAULT;
    }

    return dwError;
}

DWORD
DVDSetupSendKey(
    ATAPI_COMMAND_PACKET  *pCmd,
    PDVD_COPY_PROTECT_KEY  pKey,
    RKFMT_CHLGKEY         *keyBuf
    )
{
    BYTE   KeyType;
    BYTE   agid;
    DWORD  dwRet;
    DWORD  dwTmp;
    PRKCDB pcdb = (PRKCDB)pCmd;
    PVOID  pdata = &(pKey->KeyData[0]);

    KeyType = (BYTE)pKey->KeyType;
    agid = (BYTE)pKey->SessionId;

    pcdb->OpCode = DVDOP_SEND_KEY;
    pcdb->Lun = 0;
    pcdb->KeyFmt = (agid << 6) | KeyType;

    if (
        !KeyType || KeyType > DvdBusKey2 ||
        (pKey->KeyLength < ((dwRet = rkret[KeyType]) >> 24))
    ) {
        return 0;
    }

    keyBuf->Len = (WORD)((dwRet >> 16) - (2 << 8));
    keyBuf->Reserved[0] = keyBuf->Reserved[1] = 0;

    if (KeyType == DvdBusKey2) {
        for (dwTmp = 0; dwTmp < 5; dwTmp++) {
            *((PBYTE)(&keyBuf->chlgkey) + dwTmp) = *((PBYTE)pdata + dwTmp);
        }

        for (;dwTmp < 8; dwTmp++) {
            *((PBYTE)(&keyBuf->chlgkey) + dwTmp) = 0;
        }
    }
    else {
        for (dwTmp = 0; dwTmp < ((dwRet >> 26) - 1); dwTmp++ ) {
            *((PDWORD)(&keyBuf->chlgkey) + dwTmp) = *((PDWORD)pdata + dwTmp);
        }
    }

    *(PDWORD)(&pcdb->Reserved) = dwRet;

    pcdb->LBA = 0;
    pcdb->NACA = 0;

    return (EndSwap(dwRet));
}

DWORD
CSHXDiskAndCD::DVDSendKey(
    PIOREQ pIOReq
    )
{
    DWORD                 dwError = ERROR_SUCCESS;
    ATAPI_COMMAND_PACKET  CmdPkt;
    PDVD_COPY_PROTECT_KEY pKey = (PDVD_COPY_PROTECT_KEY)pIOReq->pInBuf;
    DWORD                 dwLength;
    RKFMT_CHLGKEY         keyBuf;
    SGX_BUF               SgBuf;
    DWORD                 dwRet;

    memset(&CmdPkt, 0, sizeof(ATAPI_COMMAND_PACKET));

    if (IOCTL_DVD_END_SESSION == pIOReq->dwCode) {
        BYTE bAgid;
        pKey->KeyType = DvdAGID;
        bAgid= (BYTE)pKey->SessionId;
        if (bAgid == -1) {
            bAgid = 0;
        }
        dwLength = DVDSetupReadTitleKey(&CmdPkt, -1, bAgid, 0);
    }
    else {
        dwLength = DVDSetupSendKey(&CmdPkt, pKey, &keyBuf);
    }

    SgBuf.sb_len = dwLength;
    SgBuf.sb_buf = (PBYTE) &keyBuf;

    if (AtapiSendCommand(&CmdPkt)) {
        if (!AtapiSendData(&SgBuf, 1, &dwRet)) {
            DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (TEXT(
                "Atapi!CSHXDiskAndCD::DVDSendKey> Failed to execute command %d\r\n"
                ), CmdPkt.Opcode));
            dwError = ERROR_WRITE_FAULT;
        }
    }
    else {
      dwError = ERROR_GEN_FAILURE;
    }

    return dwError;
}

DWORD
CSHXDiskAndCD::DVDSetRegion(
    PIOREQ pIOReq
    )
{
    return ERROR_NOT_SUPPORTED;
}

/*
    CSHXDiskAndCD::DVDGetRegion

        Return a bitfield which describes the regions in which the mounted
        disc can be played.

    Return

        Success.

    Notes

        READ DVD STRUCTURE Data Format with Format field DVDSTRUCT_FMT_COPY
        returns the Region Management Information, which describes the regions
        in which the disc can be played.  Each bit represents one of eight
        regions.  If a bit is cleared in this field, the disc can be played in
        the corresponding region.  If a bit is set in this field, the disc can
        not be played in the corresponding region.

        We perform an XOR with this field.

        For more information on the READ DVD STRUCTURE command, see SFF8090i v5
        R0.10, 13.25.

        The READ DVD STRUCTURE with Format field = 0x01 return data is of the
        following form:

        Byte 0 DVD STRUCTURE Data Length (MSB)
        Byte 1 DVD STRUCTURE Data Length (LSB)
        Byte 2 Reserved
        Byte 3 Reserved
        Byte 4 Copyright Protection System Type
        Byte 5 Region Management Information
        Byte 6 Reserved
        Byte 7 Reserved
*/
BOOL
CSHXDiskAndCD::DVDGetCopySystem(
    LPBYTE pbCopySystem,
    LPBYTE pbRegionManagement
    )
{
    BOOL                 fSuccess = FALSE;
    ATAPI_COMMAND_PACKET CmdPkt;
    PRDVDCDB             pCmd = (PRDVDCDB)&CmdPkt;
    RDVDFMT_Copy         fmtCopy;
    SGX_BUF              SgBuf;
    DWORD                dwRet;

    DEBUGCHK(NULL != pbCopySystem);
    DEBUGCHK(NULL != pbRegionManagement);

    *pbCopySystem = 0;
    *pbRegionManagement = 0;

    memset(&CmdPkt, 0, sizeof(ATAPI_COMMAND_PACKET));
    memset(&fmtCopy, 0, sizeof(RDVDFMT_Copy));

    pCmd->OpCode = DVDOP_READ_DVD_STRUC;
    pCmd->Format = DVDSTRUC_FMT_COPY;
    pCmd->Len = sizeof (RDVDFMT_Copy) << 8; // endian swap length
    // pCmd->Len = keyLength << 8;
    SgBuf.sb_len = sizeof(RDVDFMT_Copy);
    SgBuf.sb_buf = (PBYTE) &fmtCopy;

    m_dwDeviceFlags &= ~DFLAGS_MEDIA_ISDVD;

    // attempt to detect if media is present
    if (!AtapiIsUnitReady()) {
        DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (_T(
            "Atapi!CSHXDiskAndCD::DVDGetCopySystem> DVD not present\r\n"
            )));
       goto exit;
    }

    // fmtCopy is a struct of two DWORDs; we need to return 4th and 5th bytes
    if (AtapiSendCommand(&CmdPkt)) {
        if (AtapiReceiveData(&SgBuf, 1, &dwRet)) {
            *pbCopySystem = (BYTE)(fmtCopy.Data & 0xFF);              // 4th byte
            *pbRegionManagement = (BYTE)((fmtCopy.Data >> 8) & 0xFF); // 5th byte
            *pbRegionManagement = *pbRegionManagement ^ 0xFF;         // supported regions are 1s
            fSuccess = TRUE;
        }
    }

exit:;

    return fSuccess;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -