?? dvdioctl.cpp
字號:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <atamain.h>
#include <atapipcicd.h>
static
DWORD
rkret[] =
{
sizeof (RKFMT_AGID) << 24,
sizeof (RKFMT_CHLGKEY) << 24,
sizeof (RKFMT_BUS) << 24,
sizeof (RKFMT_BUS) << 24,
sizeof (RKFMT_TITLE) << 24,
0,
0,
0,
sizeof (RKFMT_RPC) << 24,
};
DWORD
EndSwap(
DWORD dwInput
)
{
register DWORD dwResult;
dwResult = (dwInput << 24) | ((dwInput & 0xff00) << 8) | ((dwInput & 0xff0000) >> 8) | (dwInput >> 24);
return(dwResult);
}
DWORD
DVDSetupReadTitleKey(
ATAPI_COMMAND_PACKET *pCmdPkt,
BYTE bKeyType,
BYTE bAgid,
DWORD dwLBA
)
{
DWORD dwRet;
PRKCDB pcdb = (PRKCDB)(pCmdPkt);
pcdb->OpCode = DVDOP_REPORT_KEY;
pcdb->KeyFmt = (bAgid << 6) | bKeyType;
pcdb->Lun = 0;
if (bKeyType >= (sizeof(rkret) / sizeof(DWORD))) {
dwRet = 0;
}
else {
dwRet = rkret[bKeyType];
}
*(PDWORD)(&pcdb->Reserved) = dwRet;
pcdb->LBA = EndSwap(dwLBA);
pcdb->NACA = 0;
return (EndSwap(dwRet));
}
DWORD
DVDSetupReadDiscKey(
ATAPI_COMMAND_PACKET *pCmdPkt,
BYTE bAgid
)
{
PRDVDCDB pcdb = (PRDVDCDB)(pCmdPkt);
pcdb->OpCode = DVDOP_READ_DVD_STRUC;
pcdb->Lun = 0;
*((DWORD *)&pcdb->RMDLBA) = 0;
pcdb->Layer = 0;
pcdb->Format = DVDSTRUC_FMT_DISCKEY;
pcdb->Len = (USHORT)(sizeof (RKFMT_DISC) << 8 | sizeof (RKFMT_DISC) >>8);
pcdb->agid = bAgid;
pcdb->NACA = 0;
return (sizeof (RKFMT_DISC));
}
DWORD
DVDSetupReadKey(
ATAPI_COMMAND_PACKET *pCmdPkt,
PDVD_COPY_PROTECT_KEY pKey
)
{
DWORD dwRet = 0;
switch (pKey->KeyType) {
case DvdTitleKey:
dwRet = DVDSetupReadTitleKey(pCmdPkt, (BYTE)(pKey->KeyType),
(BYTE)pKey->SessionId, pKey->StartAddr + 1);
break;
case DvdDriveKey:
dwRet = DVDSetupReadDiscKey(pCmdPkt, (BYTE)((pKey->SessionId) << 6));
break;
default:
dwRet = DVDSetupReadTitleKey(pCmdPkt, (BYTE)(pKey->KeyType),
(BYTE)pKey->SessionId, 0);
}
return dwRet;
}
DWORD
CopyDVDKey(
DWORD dwKeyLength,
PDVD_COPY_PROTECT_KEY pKey,
PRKFMT_TITLE pTitle)
{
DWORD dwTmp;
PBYTE psrc, pdest;
dwTmp = dwKeyLength - 4;
pdest = (PBYTE)&(pKey->KeyData[0]);
switch (pKey->KeyType) {
case DvdTitleKey:
pKey->KeyFlags = pTitle->cgms;
dwTmp--;
psrc = (PBYTE)&(pTitle->title[0]);
pdest = (PBYTE)&(pKey->KeyData[0]);
break;
case DvdAGID:
pKey->SessionId = ((PRKFMT_AGID)pTitle)->agid >> 6;
dwTmp = 0;
break;
default:
psrc = (PBYTE)&(pTitle->cgms);
pdest = (PBYTE)&(pKey->KeyData[0]);
break;
}
for (;dwTmp >0; dwTmp--) {
*pdest++ = *psrc++;
}
return TRUE;
}
DWORD
CPCIDiskAndCD::DVDReadKey(
PIOREQ pIOReq
)
{
DWORD dwError = ERROR_SUCCESS;
SGX_BUF SgBuf;
ATAPI_COMMAND_PACKET CmdPkt;
PDVD_COPY_PROTECT_KEY pKey = (PDVD_COPY_PROTECT_KEY)pIOReq->pInBuf;
DWORD dwLength;
RKFMT_DISC keyBuf;
DWORD dwRet;
memset(&CmdPkt, 0, sizeof(ATAPI_COMMAND_PACKET));
if (IOCTL_DVD_START_SESSION == pIOReq->dwCode) {
pKey->KeyType = DvdAGID;
// TODO: Check region
dwLength = DVDSetupReadTitleKey(&CmdPkt, DvdAGID, 0, 0);
}
else {
dwLength = DVDSetupReadKey(&CmdPkt, pKey);
}
if (dwLength > pKey->KeyLength) {
DEBUGMSG(ZONE_ERROR, (TEXT(
"Atapi!CPCIDiskAndCD::DVDReadKey> illegal key request\r\n"
)));
return ERROR_INVALID_PARAMETER;
}
SgBuf.sb_len = dwLength;
SgBuf.sb_buf = (PBYTE) &keyBuf;
if (AtapiSendCommand(&CmdPkt)) {
if (AtapiReceiveData(&SgBuf, 1, &dwRet)) {
CopyDVDKey(dwLength, pKey, (PRKFMT_TITLE)&keyBuf);
}
else {
DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (TEXT(
"Atapi!CPCIDiskAndCD::DVDReadKey> failed to execute command %d\r\n"
), CmdPkt.Opcode));
dwError = ERROR_READ_FAULT;
}
}
else {
dwError = ERROR_GEN_FAILURE;
}
return dwError;
}
/*
CPCIDiskAndCD::DVDGetRegion
Return the Region Playback Control (RPC) setting.
Return
Win32 error.
Populate the DVD_REGIONCE struct nested in the supplied IOREQ. If
the target drive is a virgin drive, i.e., its RPC Setting (Region) has
never been set, then return 0xFF as its Region.
Notes
For more information on the REPORT KEY command, see SFF8090i v% R0.10,
13.32.
The REPORT KEY data format with (KEY format = 001000b, Key Class = 0)
is of the following form:
Byte 0 REPORT KEY Data Length (MSB)
Byte 1 REPORT KEY Data Length (LSB)
Byte 2 Reserved
Byte 3 Reserved
Byte 4 RPC State
bit
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Type Code |Vendor Resets Remaining|User Controlled Changes|
Byte 5 Region Mask
Byte 6 RPC Scheme
Byte 7 Reserved
RPC State Type Code (Proper RPC State (4.13.3))
-------------------
00b | NONE; No drive region setting (virgin)
01b | SET; Drive region is set
10b | LAST CHANGE; Drive region is set, with additional restrictions
| required to make a change
11b | Drive region has been set permanently, but may be reset by the
| vendor, if necessary
*/
#ifdef DEBUG
#define DUMP_REPORT_KEY(x) \
if ((x.ResetCounts & 0xC0) == 0) { \
DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (_T( \
"Atapi!CPCIDiskAndCD::DVDGetRegion> RPC State=NONE; No drive region setting\r\n" \
))); \
} \
else if ((x.ResetCounts & 0xC0) == 0x40) { \
DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (_T( \
"Atapi!CPCIDiskAndCD::DVDGetRegion> RPC State=SET; Drive region set\r\n" \
))); \
} \
else if ((x.ResetCounts & 0xC0) == 0x80) { \
DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (_T( \
"Atapi!CPCIDiskAndCD::DVDGetRegion> RPC State=LAST CHANCE; Drive region set--last chance to set region\r\n" \
))); \
} \
else if ((x.ResetCounts & 0xC0) == 0xC0) { \
DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (_T( \
"Atapi!CPCIDiskAndCD::DVDGetRegion> RPC State=PERM; Drive region set permanently\r\n" \
))); \
} \
DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (_T( \
"Atapi!CPCIDiskAndCD::DVDGetRegion> %u vendor resets available\r\n" \
), (x.ResetCounts & 0x38) >> 3)); \
DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (_T( \
"Atapi!CPCIDiskAndCD::DVDGetRegion> %u user-controlled changes available\r\n" \
), x.ResetCounts & 0x07)); \
DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (_T( \
"Atapi!CPCIDiskAndCD::DVDGetRegion> Region mask=%u\r\n" \
), x.SystemRegion ^ 0xFF)); \
DEBUGMSG(ZONE_ERROR|ZONE_CDROM, (_T( \
"Atapi!CPCIDiskAndCD::DVDGetRegion> RPC Scheme=%u\r\n" \
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -