?? dvdioctl.cpp
字號:
), x.RPCVer));
#else
#define DUMP_REPORT_KEY(x)
#endif
DWORD
CPCIDiskAndCD::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!CPCIDiskAndCD::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!CPCIDiskAndCD::DVDGetRegion> Region has never been set\r\n"
)));
preg->SystemRegion = 0xFF;
preg->ResetCount = 5;
}
}
else {
DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (TEXT(
"Atapi!CPCIDiskAndCD::DVDGetRegion> Failed to receive REPORT KEY response\r\n"
)));
dwError = ERROR_READ_FAULT;
}
}
else {
DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (TEXT(
"Atapi!CPCIDiskAndCD::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
CPCIDiskAndCD::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!CPCIDiskAndCD::DVDSendKey> Failed to execute command %d\r\n"
), CmdPkt.Opcode));
dwError = ERROR_WRITE_FAULT;
}
}
else {
dwError = ERROR_GEN_FAILURE;
}
return dwError;
}
DWORD
CPCIDiskAndCD::DVDSetRegion(
PIOREQ pIOReq
)
{
return ERROR_NOT_SUPPORTED;
}
/*
CPCIDiskAndCD::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
CPCIDiskAndCD::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!CPCIDiskAndCD::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 + -