ioctl.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 2,124 行 · 第 1/4 页

C
2,124
字号
#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 )    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 = SolarisSendUSCSI( i_fd, &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 )    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 );}/***************************************************************************** * SolarisSendUSCSI: send a USCSICMD structure to the Solaris kernel * for execution ***************************************************************************** * When available, this function uses the function smedia_uscsi_cmd() * from Solaris' libsmedia library (Solaris 9 or newer) to execute the * USCSI command.  smedia_uscsi_cmd() allows USCSI commands for * non-root users on removable media devices on Solaris 9; sending the * USCSI command directly to the device using the USCSICMD ioctl fails * with an EPERM error on Solaris 9. * * The code will fall back to the USCSICMD ioctl method, when * libsmedia.so is not available or does not export the * smedia_uscsi_cmd() function (on Solaris releases upto and including * Solaris 8). Fortunatelly, on these old releases non-root users are * allowed to perform USCSICMD ioctls on removable media devices. *****************************************************************************/static int SolarisSendUSCSI( int i_fd, struct uscsi_cmd *p_sc ){    void *p_handle;    /* We use static variables to keep track of the libsmedia symbols, which     * is harmless even in a multithreaded program because the library and     * its symbols will always be mapped at the same address. */    static int b_tried = 0;    static int b_have_sm = 0;    static void * (*p_get_handle) ( int32_t );    static int (*p_uscsi_cmd) ( void *, struct uscsi_cmd * );    static int (*p_release_handle) ( void * );    if( !b_tried )    {        void *p_lib;        p_lib = dlopen( "libsmedia.so", RTLD_NOW );        if( p_lib )        {            p_get_handle = dlsym( p_lib, "smedia_get_handle" );            p_uscsi_cmd = dlsym( p_lib, "smedia_uscsi_cmd" );            p_release_handle = dlsym( p_lib, "smedia_release_handle" );            if( p_get_handle && p_uscsi_cmd && p_release_handle )            {                b_have_sm = 1;            }            else            {                dlclose( p_lib );            }        }        b_tried = 1;    }    if( b_have_sm && (p_handle = p_get_handle(i_fd)) )    {        int i_ret = p_uscsi_cmd( p_handle, p_sc );        p_release_handle( p_handle );        return i_ret;    }    return ioctl( i_fd, USCSICMD, p_sc );}#endif#if defined( WIN32 )/***************************************************************************** * 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 + =
减小字号Ctrl + -
显示快捷键?