📄 ioctl.c
字号:
i_ret = ioctl( i_fd, USCSICMD, &sc );
if( i_ret < 0 || sc.uscsi_status )
{
i_ret = -1;
}
/* Do we want to return the cp_sec flag perhaps? */
/* a->lstk.cpm = (buf[ 4 ] >> 7) & 1; */
/* a->lstk.cp_sec = (buf[ 4 ] >> 6) & 1; */
/* a->lstk.cgms = (buf[ 4 ] >> 4) & 3; */
memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
#elif defined( DARWIN_DVD_IOCTL )
INIT_DVDIOCTL( dk_dvd_report_key_t, DVDTitleKeyInfo,
kDVDKeyFormatTitleKey );
dvd.address = i_pos;
dvd.grantID = *pi_agid;
dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
memcpy( p_key, dvdbs.titleKeyValue, DVD_KEY_SIZE );
#elif defined( WIN32 ) || defined( SYS_CYGWIN )
if( WIN2K ) /* NT/2k/XP */
{
DWORD tmp;
uint8_t buffer[DVD_TITLE_KEY_LENGTH];
PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
memset( &buffer, 0, sizeof( buffer ) );
key->KeyLength = DVD_TITLE_KEY_LENGTH;
key->SessionId = *pi_agid;
key->KeyType = DvdTitleKey;
key->KeyFlags = 0;
key->Parameters.TitleOffset.QuadPart = (LONGLONG) i_pos *
2048 /*DVDCSS_BLOCK_SIZE*/;
i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
}
else
{
INIT_SSC( GPCMD_REPORT_KEY, 12 );
ssc.CDBByte[ 2 ] = ( i_pos >> 24 ) & 0xff;
ssc.CDBByte[ 3 ] = ( i_pos >> 16 ) & 0xff;
ssc.CDBByte[ 4 ] = ( i_pos >> 8 ) & 0xff;
ssc.CDBByte[ 5 ] = ( i_pos ) & 0xff;
ssc.CDBByte[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
i_ret = WinSendSSC( i_fd, &ssc );
memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
}
#elif defined( __QNXNTO__ )
INIT_CPT( GPCMD_REPORT_KEY, 12 );
p_cpt->cam_cdb[ 2 ] = ( i_pos >> 24 ) & 0xff;
p_cpt->cam_cdb[ 3 ] = ( i_pos >> 16 ) & 0xff;
p_cpt->cam_cdb[ 4 ] = ( i_pos >> 8 ) & 0xff;
p_cpt->cam_cdb[ 5 ] = ( i_pos ) & 0xff;
p_cpt->cam_cdb[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
#elif defined( SYS_OS2 )
INIT_SSC( GPCMD_REPORT_KEY, 12 );
sdc.command[ 2 ] = ( i_pos >> 24 ) & 0xff;
sdc.command[ 3 ] = ( i_pos >> 16 ) & 0xff;
sdc.command[ 4 ] = ( i_pos >> 8 ) & 0xff;
sdc.command[ 5 ] = ( i_pos ) & 0xff;
sdc.command[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
&sdc, sizeof(sdc), &ulParamLen,
p_buffer, sizeof(p_buffer), &ulDataLen);
memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
#else
# error "DVD ioctls are unavailable on this system"
#endif
return i_ret;
}
/*****************************************************************************
* ioctl_ReportAgid: get AGID from the drive
*****************************************************************************/
int ioctl_ReportAgid( int i_fd, int *pi_agid )
{
int i_ret;
#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_authinfo auth_info;
memset( &auth_info, 0, sizeof( auth_info ) );
auth_info.type = DVD_LU_SEND_AGID;
auth_info.lsa.agid = *pi_agid;
i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
*pi_agid = auth_info.lsa.agid;
#elif defined( HAVE_BSD_DVD_STRUCT )
struct dvd_authinfo auth_info;
memset( &auth_info, 0, sizeof( auth_info ) );
auth_info.format = DVD_REPORT_AGID;
auth_info.agid = *pi_agid;
i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
*pi_agid = auth_info.agid;
#elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 8 );
rdc.command[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
*pi_agid = p_buffer[ 7 ] >> 6;
#elif defined( HPUX_SCTL_IO )
INIT_SCTL_IO( GPCMD_REPORT_KEY, 8 );
sctl_io.cdb[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
*pi_agid = p_buffer[ 7 ] >> 6;
#elif defined( SOLARIS_USCSI )
INIT_USCSI( GPCMD_REPORT_KEY, 8 );
rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
i_ret = ioctl( i_fd, USCSICMD, &sc );
if( i_ret < 0 || sc.uscsi_status )
{
i_ret = -1;
}
*pi_agid = p_buffer[ 7 ] >> 6;
#elif defined( DARWIN_DVD_IOCTL )
INIT_DVDIOCTL( dk_dvd_report_key_t, DVDAuthenticationGrantIDInfo,
kDVDKeyFormatAGID_CSS );
dvd.grantID = *pi_agid;
dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
*pi_agid = dvdbs.grantID;
#elif defined( WIN32 ) || defined( SYS_CYGWIN )
if( WIN2K ) /* NT/2k/XP */
{
ULONG id;
DWORD tmp;
i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_START_SESSION,
&tmp, 4, &id, sizeof( id ), &tmp, NULL ) ? 0 : -1;
*pi_agid = id;
}
else
{
INIT_SSC( GPCMD_REPORT_KEY, 8 );
ssc.CDBByte[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
i_ret = WinSendSSC( i_fd, &ssc );
*pi_agid = p_buffer[ 7 ] >> 6;
}
#elif defined( __QNXNTO__ )
INIT_CPT( GPCMD_REPORT_KEY, 8 );
p_cpt->cam_cdb[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
*pi_agid = p_buffer[ 7 ] >> 6;
#elif defined( SYS_OS2 )
INIT_SSC( GPCMD_REPORT_KEY, 8 );
sdc.command[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
&sdc, sizeof(sdc), &ulParamLen,
p_buffer, sizeof(p_buffer), &ulDataLen);
*pi_agid = p_buffer[ 7 ] >> 6;
#else
# error "DVD ioctls are unavailable on this system"
#endif
return i_ret;
}
/*****************************************************************************
* ioctl_ReportChallenge: get challenge from the drive
*****************************************************************************/
int ioctl_ReportChallenge( int i_fd, int *pi_agid, uint8_t *p_challenge )
{
int i_ret;
#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_authinfo auth_info;
memset( &auth_info, 0, sizeof( auth_info ) );
auth_info.type = DVD_LU_SEND_CHALLENGE;
auth_info.lsc.agid = *pi_agid;
i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
memcpy( p_challenge, auth_info.lsc.chal, DVD_CHALLENGE_SIZE );
#elif defined( HAVE_BSD_DVD_STRUCT )
struct dvd_authinfo auth_info;
memset( &auth_info, 0, sizeof( auth_info ) );
auth_info.format = DVD_REPORT_CHALLENGE;
auth_info.agid = *pi_agid;
i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
memcpy( p_challenge, auth_info.keychal, DVD_CHALLENGE_SIZE );
#elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 16 );
rdc.command[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
#elif defined( HPUX_SCTL_IO )
INIT_SCTL_IO( GPCMD_REPORT_KEY, 16 );
sctl_io.cdb[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
#elif defined( SOLARIS_USCSI )
INIT_USCSI( GPCMD_REPORT_KEY, 16 );
rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
i_ret = ioctl( i_fd, USCSICMD, &sc );
if( i_ret < 0 || sc.uscsi_status )
{
i_ret = -1;
}
memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
#elif defined( DARWIN_DVD_IOCTL )
INIT_DVDIOCTL( dk_dvd_report_key_t, DVDChallengeKeyInfo,
kDVDKeyFormatChallengeKey );
dvd.grantID = *pi_agid;
i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
memcpy( p_challenge, dvdbs.challengeKeyValue, DVD_CHALLENGE_SIZE );
#elif defined( WIN32 ) || defined( SYS_CYGWIN )
if( WIN2K ) /* NT/2k/XP */
{
DWORD tmp;
uint8_t buffer[DVD_CHALLENGE_KEY_LENGTH];
PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
memset( &buffer, 0, sizeof( buffer ) );
key->KeyLength = DVD_CHALLENGE_KEY_LENGTH;
key->SessionId = *pi_agid;
key->KeyType = DvdChallengeKey;
key->KeyFlags = 0;
i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
if( i_ret < 0 )
{
return i_ret;
}
memcpy( p_challenge, key->KeyData, DVD_CHALLENGE_SIZE );
}
else
{
INIT_SSC( GPCMD_REPORT_KEY, 16 );
ssc.CDBByte[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
i_ret = WinSendSSC( i_fd, &ssc );
memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
}
#elif defined( __QNXNTO__ )
INIT_CPT( GPCMD_REPORT_KEY, 16 );
p_cpt->cam_cdb[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
#elif defined( SYS_OS2 )
INIT_SSC( GPCMD_REPORT_KEY, 16 );
sdc.command[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
&sdc, sizeof(sdc), &ulParamLen,
p_buffer, sizeof(p_buffer), &ulDataLen);
memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
#else
# error "DVD ioctls are unavailable on this system"
#endif
return i_ret;
}
/*****************************************************************************
* ioctl_ReportASF: get ASF from the drive
*****************************************************************************/
int ioctl_ReportASF( int i_fd, int *pi_remove_me, int *pi_asf )
{
int i_ret;
#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_authinfo auth_info;
memset( &auth_info, 0, sizeof( auth_info ) );
auth_info.type = DVD_LU_SEND_ASF;
auth_info.lsasf.asf = *pi_asf;
i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
*pi_asf = auth_info.lsasf.asf;
#elif defined( HAVE_BSD_DVD_STRUCT )
struct dvd_authinfo auth_info;
memset( &auth_info, 0, sizeof( auth_info ) );
auth_info.format = DVD_REPORT_ASF;
auth_info.asf = *pi_asf;
i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
*pi_asf = auth_info.asf;
#elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 8 );
rdc.command[ 10 ] = DVD_REPORT_ASF;
i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
*pi_asf = p_buffer[ 7 ] & 1;
#elif defined( HPUX_SCTL_IO )
INIT_SCTL_IO( GPCMD_REPORT_KEY, 8 );
sctl_io.cdb[ 10 ] = DVD_REPORT_ASF;
i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
*pi_asf = p_buffer[ 7 ] & 1;
#elif defined( SOLARIS_USCSI )
INIT_USCSI( GPCMD_REPORT_KEY, 8 );
rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_ASF;
i_ret = ioctl( i_fd, USCSICMD, &sc );
if( i_ret < 0 || sc.uscsi_status )
{
i_ret = -1;
}
*pi_asf = p_buffer[ 7 ] & 1;
#elif defined( DARWIN_DVD_IOCTL )
INIT_DVDIOCTL( dk_dvd_report_key_t, DVDAuthenticationSuccessFlagInfo,
kDVDKeyFormatASF );
i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
*pi_asf = dvdbs.successFlag;
#elif defined( WIN32 ) || defined( SYS_CYGWIN )
if( WIN2K ) /* NT/2k/XP */
{
DWORD tmp;
uint8_t buffer[DVD_ASF_LENGTH];
PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
memset( &buffer, 0, sizeof( buffer ) );
key->KeyLength = DVD_ASF_LENGTH;
key->KeyType = DvdAsf;
key->KeyFlags = 0;
((PDVD_ASF)key->KeyData)->SuccessFlag = *pi_asf;
i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
if( i_ret < 0 )
{
return i_ret;
}
*pi_asf = ((PDVD_ASF)key->KeyData)->SuccessFlag;
}
else
{
INIT_SSC( GPCMD_REPORT_KEY, 8 );
ssc.CDBByte[ 10 ] = DVD_REPORT_ASF;
i_ret = WinSendSSC( i_fd, &ssc );
*pi_asf = p_buffer[ 7 ] & 1;
}
#elif defined( __QNXNTO__ )
INIT_CPT( GPCMD_REPORT_KEY, 8 );
p_cpt->cam_cdb[ 10 ] = DVD_REPORT_ASF;
i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
*pi_asf = p_buffer[ 7 ] & 1;
#elif defined( SYS_OS2 )
INIT_SSC( GPCMD_REPORT_KEY, 8 );
sdc.command[ 10 ] = DVD_REPORT_ASF;
i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
&sdc, sizeof(sdc), &ulParamLen,
p_buffer, sizeof(p_buffer), &ulDataLen);
*pi_asf = p_buffer[ 7 ] & 1;
#else
# error "DVD ioctls are unavailable on this system"
#endif
return i_ret;
}
/*****************************************************************************
* ioctl_ReportKey1: get the first key from the drive
*****************************************************************************/
int ioctl_ReportKey1( int i_fd, int *pi_agid, uint8_t *p_key )
{
int i_ret;
#if defined( HAVE_LINUX_DVD_STRUCT )
dvd_authinfo auth_info;
memset( &auth_info, 0, sizeof( auth_info ) );
auth_info.type = DVD_LU_SEND_KEY1;
auth_info.lsk.agid = *pi_agid;
i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
memcpy( p_key, auth_info.lsk.key, DVD_KEY_SIZE );
#elif defined( HAVE_BSD_DVD_STRUCT )
struct dvd_authinfo auth_info;
memset( &auth_info, 0, sizeof( auth_info ) );
auth_info.format = DVD_REPORT_KEY1;
auth_info.agid = *pi_agid;
i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -