📄 ioctl.c
字号:
auth_info.format = DVD_REPORT_RPC;
i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );
*p_type = auth_info.reg_type;
*p_mask = auth_info.region; // ??
*p_scheme = auth_info.rpc_scheme;
#elif defined( SYS_BEOS )
INIT_RDC( GPCMD_REPORT_KEY, 8 );
rdc.command[ 10 ] = DVD_REPORT_RPC;
i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
*p_type = p_buffer[ 4 ] >> 6;
*p_mask = p_buffer[ 5 ];
*p_scheme = p_buffer[ 6 ];
#elif defined( HPUX_SCTL_IO )
INIT_SCTL_IO( GPCMD_REPORT_KEY, 8 );
sctl_io.cdb[ 10 ] = DVD_REPORT_RPC;
i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
*p_type = p_buffer[ 4 ] >> 6;
*p_mask = p_buffer[ 5 ];
*p_scheme = p_buffer[ 6 ];
#elif defined( SOLARIS_USCSI )
INIT_USCSI( GPCMD_REPORT_KEY, 8 );
rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_RPC;
i_ret = ioctl( i_fd, USCSICMD, &sc );
if( i_ret < 0 || sc.uscsi_status )
{
i_ret = -1;
}
*p_type = p_buffer[ 4 ] >> 6;
*p_mask = p_buffer[ 5 ];
*p_scheme = p_buffer[ 6 ];
#elif defined( DARWIN_DVD_IOCTL )
INIT_DVDIOCTL( dk_dvd_report_key_t, DVDRegionPlaybackControlInfo,
kDVDKeyFormatRegionState );
dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
i_ret = ioctl( i_fd, DKIOCDVDREPORTKEY, &dvd );
*p_type = dvdbs.typeCode;
*p_mask = dvdbs.driveRegion;
*p_scheme = dvdbs.rpcScheme;
#elif defined( WIN32 ) || defined( SYS_CYGWIN )
if( WIN2K ) /* NT/2k/XP */
{
DWORD tmp;
uint8_t buffer[DVD_RPC_KEY_LENGTH];
PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
memset( &buffer, 0, sizeof( buffer ) );
key->KeyLength = DVD_RPC_KEY_LENGTH;
key->KeyType = DvdGetRpcKey;
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;
}
*p_type = ((PDVD_RPC_KEY)key->KeyData)->TypeCode;
*p_mask = ((PDVD_RPC_KEY)key->KeyData)->RegionMask;
*p_scheme = ((PDVD_RPC_KEY)key->KeyData)->RpcScheme;
}
else
{
INIT_SSC( GPCMD_REPORT_KEY, 8 );
ssc.CDBByte[ 10 ] = DVD_REPORT_RPC;
i_ret = WinSendSSC( i_fd, &ssc );
*p_type = p_buffer[ 4 ] >> 6;
*p_mask = p_buffer[ 5 ];
*p_scheme = p_buffer[ 6 ];
}
#elif defined( __QNXNTO__ )
INIT_CPT( GPCMD_REPORT_KEY, 8 );
p_cpt->cam_cdb[ 10 ] = DVD_REPORT_RPC;
i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
*p_type = p_buffer[ 4 ] >> 6;
*p_mask = p_buffer[ 5 ];
*p_scheme = p_buffer[ 6 ];
#elif defined( SYS_OS2 )
INIT_SSC( GPCMD_REPORT_KEY, 8 );
sdc.command[ 10 ] = DVD_REPORT_RPC;
i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
&sdc, sizeof(sdc), &ulParamLen,
p_buffer, sizeof(p_buffer), &ulDataLen);
*p_type = p_buffer[ 4 ] >> 6;
*p_mask = p_buffer[ 5 ];
*p_scheme = p_buffer[ 6 ];
#else
# error "DVD ioctls are unavailable on this system"
#endif
return i_ret;
}
/*****************************************************************************
* ioctl_SendRPC: set RPC status for the drive
*****************************************************************************/
int ioctl_SendRPC( int i_fd, int i_pdrc )
{
int i_ret;
#if defined( HAVE_LINUX_DVD_STRUCT ) && defined( DVD_HOST_SEND_RPC_STATE )
dvd_authinfo auth_info;
memset( &auth_info, 0, sizeof( auth_info ) );
auth_info.type = DVD_HOST_SEND_RPC_STATE;
auth_info.hrpcs.pdrc = i_pdrc;
i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );
#elif defined( HAVE_LINUX_DVD_STRUCT )
/* FIXME: OpenBSD doesn't know this */
i_ret = -1;
#elif defined( HAVE_BSD_DVD_STRUCT )
struct dvd_authinfo auth_info;
memset( &auth_info, 0, sizeof( auth_info ) );
auth_info.format = DVD_SEND_RPC;
auth_info.region = i_pdrc;
i_ret = ioctl( i_fd, DVDIOCSENDKEY, &auth_info );
#elif defined( SYS_BEOS )
INIT_RDC( GPCMD_SEND_KEY, 8 );
rdc.command[ 10 ] = DVD_SEND_RPC;
p_buffer[ 1 ] = 6;
p_buffer[ 4 ] = i_pdrc;
i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );
#elif defined( HPUX_SCTL_IO )
INIT_SCTL_IO( GPCMD_SEND_KEY, 8 );
sctl_io.cdb[ 10 ] = DVD_SEND_RPC;
p_buffer[ 1 ] = 6;
p_buffer[ 4 ] = i_pdrc;
i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );
#elif defined( SOLARIS_USCSI )
INIT_USCSI( GPCMD_SEND_KEY, 8 );
rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_RPC;
p_buffer[ 1 ] = 6;
p_buffer[ 4 ] = i_pdrc;
i_ret = ioctl( i_fd, USCSICMD, &sc );
if( i_ret < 0 || sc.uscsi_status )
{
i_ret = -1;
}
#elif defined( DARWIN_DVD_IOCTL )
INIT_DVDIOCTL( dk_dvd_send_key_t, DVDRegionPlaybackControlInfo,
kDVDKeyFormatSetRegion );
dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
dvdbs.driveRegion = i_pdrc;
i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
#elif defined( WIN32 ) || defined( SYS_CYGWIN )
if( WIN2K ) /* NT/2k/XP */
{
INIT_SPTD( GPCMD_SEND_KEY, 8 );
sptd.Cdb[ 10 ] = DVD_SEND_RPC;
p_buffer[ 1 ] = 6;
p_buffer[ 4 ] = i_pdrc;
i_ret = SEND_SPTD( i_fd, &sptd, &tmp );
}
else
{
INIT_SSC( GPCMD_SEND_KEY, 8 );
ssc.CDBByte[ 10 ] = DVD_SEND_RPC;
p_buffer[ 1 ] = 6;
p_buffer[ 4 ] = i_pdrc;
i_ret = WinSendSSC( i_fd, &ssc );
}
#elif defined( __QNXNTO__ )
INIT_CPT( GPCMD_SEND_KEY, 8 );
p_cpt->cam_cdb[ 10 ] = DVD_SEND_RPC;
p_buffer[ 1 ] = 6;
p_buffer[ 4 ] = i_pdrc;
i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);
#elif defined( SYS_OS2 )
INIT_SSC( GPCMD_SEND_KEY, 8 );
sdc.command[ 10 ] = DVD_SEND_RPC;
p_buffer[ 1 ] = 6;
p_buffer[ 4 ] = i_pdrc;
i_ret = DosDevIOCtl( i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,
&sdc, sizeof(sdc), &ulParamLen,
p_buffer, sizeof(p_buffer), &ulDataLen );
#else
# error "DVD ioctls are unavailable on this system"
#endif
return i_ret;
}
/* Local prototypes */
#if defined( SYS_BEOS )
/*****************************************************************************
* BeInitRDC: initialize a RDC structure for the BeOS kernel
*****************************************************************************
* This function initializes a BeOS raw device command structure for future
* use, either a read command or a write command.
*****************************************************************************/
static void BeInitRDC( raw_device_command *p_rdc, int i_type )
{
memset( p_rdc->data, 0, p_rdc->data_length );
switch( i_type )
{
case GPCMD_SEND_KEY:
/* leave the flags to 0 */
break;
case GPCMD_READ_DVD_STRUCTURE: case GPCMD_REPORT_KEY:
p_rdc->flags = B_RAW_DEVICE_DATA_IN; break; }
p_rdc->command[ 0 ] = i_type;
p_rdc->command[ 8 ] = (p_rdc->data_length >> 8) & 0xff;
p_rdc->command[ 9 ] = p_rdc->data_length & 0xff;
p_rdc->command_length = 12;
p_rdc->sense_data = NULL;
p_rdc->sense_data_length = 0;
p_rdc->timeout = 1000000;
}
#endif
#if defined( HPUX_SCTL_IO )
/*****************************************************************************
* HPUXInitSCTL: initialize a sctl_io structure for the HP-UX kernel
*****************************************************************************
* This function initializes a HP-UX command structure for future
* use, either a read command or a write command.
*****************************************************************************/
static void HPUXInitSCTL( struct sctl_io *sctl_io, int i_type )
{
memset( sctl_io->data, 0, sctl_io->data_length );
switch( i_type )
{
case GPCMD_SEND_KEY:
/* leave the flags to 0 */
break;
case GPCMD_READ_DVD_STRUCTURE:
case GPCMD_REPORT_KEY:
sctl_io->flags = SCTL_READ;
break;
}
sctl_io->cdb[ 0 ] = i_type;
sctl_io->cdb[ 8 ] = (sctl_io->data_length >> 8) & 0xff;
sctl_io->cdb[ 9 ] = sctl_io->data_length & 0xff;
sctl_io->cdb_length = 12;
sctl_io->max_msecs = 1000000;
}
#endif
#if defined( SOLARIS_USCSI )
/*****************************************************************************
* SolarisInitUSCSI: initialize a USCSICMD structure for the Solaris kernel
*****************************************************************************
* This function initializes a Solaris userspace scsi command structure for
* future use, either a read command or a write command.
*****************************************************************************/
static void SolarisInitUSCSI( struct uscsi_cmd *p_sc, int i_type )
{
union scsi_cdb *rs_cdb;
memset( p_sc->uscsi_cdb, 0, sizeof( union scsi_cdb ) );
memset( p_sc->uscsi_bufaddr, 0, p_sc->uscsi_buflen );
switch( i_type )
{
case GPCMD_SEND_KEY:
p_sc->uscsi_flags = USCSI_ISOLATE | USCSI_WRITE;
break;
case GPCMD_READ_DVD_STRUCTURE:
case GPCMD_REPORT_KEY:
p_sc->uscsi_flags = USCSI_ISOLATE | USCSI_READ;
break;
}
rs_cdb = (union scsi_cdb *)p_sc->uscsi_cdb;
rs_cdb->scc_cmd = i_type;
rs_cdb->cdb_opaque[ 8 ] = (p_sc->uscsi_buflen >> 8) & 0xff;
rs_cdb->cdb_opaque[ 9 ] = p_sc->uscsi_buflen & 0xff;
p_sc->uscsi_cdblen = 12;
USCSI_TIMEOUT( p_sc, 15 );
}
#endif
#if defined( WIN32 ) || defined( SYS_CYGWIN )
/*****************************************************************************
* WinInitSPTD: initialize a sptd structure
*****************************************************************************
* This function initializes a SCSI pass through command structure for future
* use, either a read command or a write command.
*****************************************************************************/
static void WinInitSPTD( SCSI_PASS_THROUGH_DIRECT *p_sptd, int i_type )
{
memset( p_sptd->DataBuffer, 0, p_sptd->DataTransferLength );
switch( i_type )
{
case GPCMD_SEND_KEY:
p_sptd->DataIn = SCSI_IOCTL_DATA_OUT;
break;
case GPCMD_READ_DVD_STRUCTURE:
case GPCMD_REPORT_KEY:
p_sptd->DataIn = SCSI_IOCTL_DATA_IN;
break;
}
p_sptd->Cdb[ 0 ] = i_type;
p_sptd->Cdb[ 8 ] = (uint8_t)(p_sptd->DataTransferLength >> 8) & 0xff;
p_sptd->Cdb[ 9 ] = (uint8_t) p_sptd->DataTransferLength & 0xff;
p_sptd->CdbLength = 12;
p_sptd->TimeOutValue = 2;
}
/*****************************************************************************
* WinInitSSC: initialize a ssc structure for the win32 aspi layer
*****************************************************************************
* This function initializes a ssc raw device command structure for future
* use, either a read command or a write command.
*****************************************************************************/
static void WinInitSSC( struct SRB_ExecSCSICmd *p_ssc, int i_type )
{
memset( p_ssc->SRB_BufPointer, 0, p_ssc->SRB_BufLen );
switch( i_type )
{
case GPCMD_SEND_KEY:
p_ssc->SRB_Flags = SRB_DIR_OUT;
break;
case GPCMD_READ_DVD_STRUCTURE:
case GPCMD_REPORT_KEY:
p_ssc->SRB_Flags = SRB_DIR_IN;
break;
}
p_ssc->SRB_Cmd = SC_EXEC_SCSI_CMD;
p_ssc->SRB_Flags |= SRB_EVENT_NOTIFY;
p_ssc->CDBByte[ 0 ] = i_type;
p_ssc->CDBByte[ 8 ] = (uint8_t)(p_ssc->SRB_BufLen >> 8) & 0xff;
p_ssc->CDBByte[ 9 ] = (uint8_t) p_ssc->SRB_BufLen & 0xff;
p_ssc->SRB_CDBLen = 12;
p_ssc->SRB_SenseLen = SENSE_LEN;
}
/*****************************************************************************
* WinSendSSC: send a ssc structure to the aspi layer
*****************************************************************************/
static int WinSendSSC( int i_fd, struct SRB_ExecSCSICmd *p_ssc )
{
HANDLE hEvent = NULL;
struct w32_aspidev *fd = (struct w32_aspidev *) i_fd;
hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if( hEvent == NULL )
{
return -1;
}
p_ssc->SRB_PostProc = hEvent;
p_ssc->SRB_HaId = LOBYTE( fd->i_sid );
p_ssc->SRB_Target = HIBYTE( fd->i_sid );
ResetEvent( hEvent );
if( fd->lpSendCommand( (void*) p_ssc ) == SS_PENDING )
WaitForSingleObject( hEvent, INFINITE );
CloseHandle( hEvent );
return p_ssc->SRB_Status == SS_COMP ? 0 : -1;
}
#endif
#if defined( __QNXNTO__ )
/*****************************************************************************
* QNXInitCPT: initialize a CPT structure for QNX Neutrino
*****************************************************************************
* This function initializes a cpt command structure for future use,
* either a read command or a write command.
*****************************************************************************/
static void QNXInitCPT( CAM_PASS_THRU * p_cpt, int i_type )
{
switch( i_type )
{
case GPCMD_SEND_KEY:
p_cpt->cam_flags = CAM_DIR_OUT;
break;
case GPCMD_READ_DVD_STRUCTURE:
case GPCMD_REPORT_KEY:
p_cpt->cam_flags = CAM_DIR_IN;
break;
}
p_cpt->cam_cdb[0] = i_type;
p_cpt->cam_cdb[ 8 ] = (p_cpt->cam_dxfer_len >> 8) & 0xff;
p_cpt->cam_cdb[ 9 ] = p_cpt->cam_dxfer_len & 0xff;
p_cpt->cam_cdb_len = 12;
p_cpt->cam_timeout = CAM_TIME_DEFAULT;
}
#endif
#if defined( SYS_OS2 )
/*****************************************************************************
* OS2InitSDC: initialize a SDC structure for the Execute SCSI-command
*****************************************************************************
* This function initializes a OS2 'execute SCSI command' structure for
* future use, either a read command or a write command.
*****************************************************************************/
static void OS2InitSDC( struct OS2_ExecSCSICmd *p_sdc, int i_type )
{
switch( i_type )
{
case GPCMD_SEND_KEY:
p_sdc->flags = 0;
break;
case GPCMD_READ_DVD_STRUCTURE:
case GPCMD_REPORT_KEY:
p_sdc->flags = EX_DIRECTION_IN;
break;
}
p_sdc->command[ 0 ] = i_type;
p_sdc->command[ 8 ] = (p_sdc->data_length >> 8) & 0xff;
p_sdc->command[ 9 ] = p_sdc->data_length & 0xff;
p_sdc->id_code = 0x31304443; // 'CD01'
p_sdc->cmd_length = 12;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -