ioctl.c

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

C
2,124
字号
/***************************************************************************** * ioctl.c: DVD ioctl replacement function ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN * $Id: ioctl.c,v 1.2 2008/03/03 08:11:37 dsqiu Exp $ * * Authors: Markus Kuespert <ltlBeBoy@beosmail.com> *          Samuel Hocevar <sam@zoy.org> *          Jon Lech Johansen <jon-vl@nanocrew.net> *          H錵an Hjort <d95hjort@dtek.chalmers.se> *          Eugenio Jarosiewicz <ej0@cise.ufl.edu> *          David Sieb鰎ger <drs-videolan@rucus.ru.ac.za> *          Alex Strelnikov <lelik@os2.ru> *          Gildas Bazin <gbazin@netcourrier.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include "config.h"#include <mplaylib.h>#include <mplaylib.h>                                    /* memcpy(), memset() */#include <sys/types.h>#if defined( WIN32 )#   include <windows.h>#   include <winioctl.h>#elif defined ( SYS_OS2 )#   define INCL_DOSFILEMGR#   define INCL_DOSDEVICES#   define INCL_DOSDEVIOCTL#   define INCL_DOSERRORS#   include <os2.h>#   include <sys/ioctl.h>#else#   include <netinet/in.h>#   include <sys/ioctl.h>#endif#ifdef DVD_STRUCT_IN_SYS_CDIO_H#   include <sys/cdio.h>#endif#ifdef DVD_STRUCT_IN_SYS_DVDIO_H#   include <sys/dvdio.h>#endif#ifdef DVD_STRUCT_IN_LINUX_CDROM_H#   include <linux/cdrom.h>#endif#ifdef DVD_STRUCT_IN_DVD_H#   include <dvd.h>#endif#ifdef DVD_STRUCT_IN_BSDI_DVDIOCTL_DVD_H#   include "bsdi_dvd.h"#endif#ifdef SYS_BEOS#   include <malloc.h>#   include <scsi.h>#endif#ifdef HPUX_SCTL_IO#   include <sys/scsi.h>#endif#ifdef SOLARIS_USCSI#   include <dlfcn.h>#   include <unistd.h>#   include <stropts.h>#   include <sys/scsi/scsi_types.h>#   include <sys/scsi/impl/uscsi.h>#endif#ifdef DARWIN_DVD_IOCTL#   include <IOKit/storage/IODVDMediaBSDClient.h>#endif#ifdef __QNXNTO__#   include <sys/mman.h>#   include <sys/dcmd_cam.h>#endif#include "common.h"#include "ioctl.h"/***************************************************************************** * Local prototypes, BeOS specific *****************************************************************************/#if defined( SYS_BEOS )static void BeInitRDC ( raw_device_command *, int );#endif/***************************************************************************** * Local prototypes, HP-UX specific *****************************************************************************/#if defined( HPUX_SCTL_IO )static void HPUXInitSCTL ( struct sctl_io *sctl_io, int i_type );#endif/***************************************************************************** * Local prototypes, Solaris specific *****************************************************************************/#if defined( SOLARIS_USCSI )static void SolarisInitUSCSI( struct uscsi_cmd *p_sc, int i_type );static int SolarisSendUSCSI( int fd, struct uscsi_cmd *p_sc );#endif/***************************************************************************** * Local prototypes, win32 (aspi) specific *****************************************************************************/#if defined( WIN32 )static void WinInitSPTD ( SCSI_PASS_THROUGH_DIRECT *, int );static void WinInitSSC  ( struct SRB_ExecSCSICmd *, int );static int  WinSendSSC  ( int, struct SRB_ExecSCSICmd * );#endif/***************************************************************************** * Local prototypes, QNX specific *****************************************************************************/#if defined( __QNXNTO__ )static void QNXInitCPT ( CAM_PASS_THRU *, int );#endif/***************************************************************************** * Local prototypes, OS2 specific *****************************************************************************/#if defined( SYS_OS2 )static void OS2InitSDC( struct OS2_ExecSCSICmd *, int );#endif/***************************************************************************** * ioctl_ReadCopyright: check whether the disc is encrypted or not *****************************************************************************/int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright ){    int i_ret;#if defined( HAVE_LINUX_DVD_STRUCT )    dvd_struct dvd;    memset( &dvd, 0, sizeof( dvd ) );    dvd.type = DVD_STRUCT_COPYRIGHT;    dvd.copyright.layer_num = i_layer;    i_ret = ioctl( i_fd, DVD_READ_STRUCT, &dvd );    *pi_copyright = dvd.copyright.cpst;#elif defined( HAVE_BSD_DVD_STRUCT )    struct dvd_struct dvd;    memset( &dvd, 0, sizeof( dvd ) );    dvd.format = DVD_STRUCT_COPYRIGHT;    dvd.layer_num = i_layer;    i_ret = ioctl( i_fd, DVDIOCREADSTRUCTURE, &dvd );    *pi_copyright = dvd.cpst;#elif defined( SYS_BEOS )    INIT_RDC( GPCMD_READ_DVD_STRUCTURE, 8 );    rdc.command[ 6 ] = i_layer;    rdc.command[ 7 ] = DVD_STRUCT_COPYRIGHT;    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );    *pi_copyright = p_buffer[ 4 ];#elif defined( HPUX_SCTL_IO )    INIT_SCTL_IO( GPCMD_READ_DVD_STRUCTURE, 8 );    sctl_io.cdb[ 6 ] = i_layer;    sctl_io.cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;    i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );    *pi_copyright = p_buffer[ 4 ];#elif defined( SOLARIS_USCSI )    INIT_USCSI( GPCMD_READ_DVD_STRUCTURE, 8 );    rs_cdb.cdb_opaque[ 6 ] = i_layer;    rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_COPYRIGHT;    i_ret = SolarisSendUSCSI(i_fd, &sc);    if( i_ret < 0 || sc.uscsi_status ) {        i_ret = -1;    }    *pi_copyright = p_buffer[ 4 ];    /* s->copyright.rmi = p_buffer[ 5 ]; */#elif defined( DARWIN_DVD_IOCTL )    INIT_DVDIOCTL( dk_dvd_read_structure_t, DVDCopyrightInfo,                   kDVDStructureFormatCopyrightInfo );    dvd.layer = i_layer;    i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );    *pi_copyright = dvdbs.copyrightProtectionSystemType;#elif defined( WIN32 )    if( WIN2K ) /* NT/2k/XP */    {        INIT_SPTD( GPCMD_READ_DVD_STRUCTURE, 8 );        /*  When using IOCTL_DVD_READ_STRUCTURE and            DVD_COPYRIGHT_DESCRIPTOR, CopyrightProtectionType            seems to be always 6 ???            To work around this MS bug we try to send a raw scsi command            instead (if we've got enough privileges to do so). */        sptd.Cdb[ 6 ] = i_layer;        sptd.Cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;        i_ret = SEND_SPTD( i_fd, &sptd, &tmp );        if( i_ret == 0 )        {            *pi_copyright = p_buffer[ 4 ];        }    }    else    {        INIT_SSC( GPCMD_READ_DVD_STRUCTURE, 8 );        ssc.CDBByte[ 6 ] = i_layer;        ssc.CDBByte[ 7 ] = DVD_STRUCT_COPYRIGHT;        i_ret = WinSendSSC( i_fd, &ssc );        *pi_copyright = p_buffer[ 4 ];    }#elif defined( __QNXNTO__ )    INIT_CPT( GPCMD_READ_DVD_STRUCTURE, 8 );    p_cpt->cam_cdb[ 6 ] = i_layer;    p_cpt->cam_cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);    *pi_copyright = p_buffer[4];#elif defined( SYS_OS2 )    INIT_SSC( GPCMD_READ_DVD_STRUCTURE, 8 );    sdc.command[ 6 ] = i_layer;    sdc.command[ 7 ] = DVD_STRUCT_COPYRIGHT;    i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,                        &sdc, sizeof(sdc), &ulParamLen,                        p_buffer, sizeof(p_buffer), &ulDataLen);    *pi_copyright = p_buffer[ 4 ];#else#   error "DVD ioctls are unavailable on this system"#endif    return i_ret;}/***************************************************************************** * ioctl_ReadDiscKey: get the disc key *****************************************************************************/int ioctl_ReadDiscKey( int i_fd, int *pi_agid, uint8_t *p_key ){    int i_ret;#if defined( HAVE_LINUX_DVD_STRUCT )    dvd_struct dvd;    memset( &dvd, 0, sizeof( dvd ) );    dvd.type = DVD_STRUCT_DISCKEY;    dvd.disckey.agid = *pi_agid;    memset( dvd.disckey.value, 0, DVD_DISCKEY_SIZE );    i_ret = ioctl( i_fd, DVD_READ_STRUCT, &dvd );    if( i_ret < 0 )    {        return i_ret;    }    memcpy( p_key, dvd.disckey.value, DVD_DISCKEY_SIZE );#elif defined( HAVE_BSD_DVD_STRUCT )    struct dvd_struct dvd;    memset( &dvd, 0, sizeof( dvd ) );    dvd.format = DVD_STRUCT_DISCKEY;    dvd.agid = *pi_agid;    memset( dvd.data, 0, DVD_DISCKEY_SIZE );    i_ret = ioctl( i_fd, DVDIOCREADSTRUCTURE, &dvd );    if( i_ret < 0 )    {        return i_ret;    }    memcpy( p_key, dvd.data, DVD_DISCKEY_SIZE );#elif defined( SYS_BEOS )    INIT_RDC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );    rdc.command[ 7 ]  = DVD_STRUCT_DISCKEY;    rdc.command[ 10 ] = *pi_agid << 6;    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );    if( i_ret < 0 )    {        return i_ret;    }    memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );#elif defined( HPUX_SCTL_IO )    INIT_SCTL_IO( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );    sctl_io.cdb[ 7 ]  = DVD_STRUCT_DISCKEY;    sctl_io.cdb[ 10 ] = *pi_agid << 6;    i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );    if( i_ret < 0 )    {        return i_ret;    }    memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );#elif defined( SOLARIS_USCSI )    INIT_USCSI( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );    rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_DISCKEY;    rs_cdb.cdb_opaque[ 10 ] = *pi_agid << 6;    i_ret = SolarisSendUSCSI( i_fd, &sc );    if( i_ret < 0 || sc.uscsi_status )    {        i_ret = -1;        return i_ret;    }    memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );#elif defined( DARWIN_DVD_IOCTL )    INIT_DVDIOCTL( dk_dvd_read_structure_t, DVDDiscKeyInfo,                   kDVDStructureFormatDiscKeyInfo );    dvd.grantID = *pi_agid;    i_ret = ioctl( i_fd, DKIOCDVDREADSTRUCTURE, &dvd );    memcpy( p_key, dvdbs.discKeyStructures, DVD_DISCKEY_SIZE );#elif defined( WIN32 )    if( WIN2K ) /* NT/2k/XP */    {        DWORD tmp;        uint8_t buffer[DVD_DISK_KEY_LENGTH];        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;        memset( &buffer, 0, sizeof( buffer ) );        key->KeyLength  = DVD_DISK_KEY_LENGTH;        key->SessionId  = *pi_agid;        key->KeyType    = DvdDiskKey;        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_key, key->KeyData, DVD_DISCKEY_SIZE );    }    else    {        INIT_SSC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );        ssc.CDBByte[ 7 ]  = DVD_STRUCT_DISCKEY;        ssc.CDBByte[ 10 ] = *pi_agid << 6;        i_ret = WinSendSSC( i_fd, &ssc );        if( i_ret < 0 )        {            return i_ret;        }        memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );    }#elif defined( __QNXNTO__ )    INIT_CPT( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );    p_cpt->cam_cdb[ 7 ] = DVD_STRUCT_DISCKEY;    p_cpt->cam_cdb[ 10 ] = *pi_agid << 6;    i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL);    memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );#elif defined ( SYS_OS2 )    INIT_SSC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );    sdc.command[ 7 ]  = DVD_STRUCT_DISCKEY;    sdc.command[ 10 ] = *pi_agid << 6;    i_ret = DosDevIOCtl(i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD,                        &sdc, sizeof(sdc), &ulParamLen,                        p_buffer, sizeof(p_buffer), &ulDataLen);    if( i_ret < 0 )    {        return i_ret;    }    memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );#else#   error "DVD ioctls are unavailable on this system"#endif    return i_ret;}/***************************************************************************** * ioctl_ReadTitleKey: get the title key *****************************************************************************/int ioctl_ReadTitleKey( int i_fd, int *pi_agid, int i_pos, 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_TITLE_KEY;    auth_info.lstk.agid = *pi_agid;    auth_info.lstk.lba = i_pos;    i_ret = ioctl( i_fd, DVD_AUTH, &auth_info );    memcpy( p_key, auth_info.lstk.title_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_TITLE_KEY;    auth_info.agid = *pi_agid;    auth_info.lba = i_pos;    i_ret = ioctl( i_fd, DVDIOCREPORTKEY, &auth_info );    memcpy( p_key, auth_info.keychal, DVD_KEY_SIZE );#elif defined( SYS_BEOS )    INIT_RDC( GPCMD_REPORT_KEY, 12 );    rdc.command[ 2 ] = ( i_pos >> 24 ) & 0xff;    rdc.command[ 3 ] = ( i_pos >> 16 ) & 0xff;    rdc.command[ 4 ] = ( i_pos >>  8 ) & 0xff;    rdc.command[ 5 ] = ( i_pos       ) & 0xff;    rdc.command[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);    i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) );    memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );#elif defined( HPUX_SCTL_IO )    INIT_SCTL_IO( GPCMD_REPORT_KEY, 12 );    sctl_io.cdb[ 2 ] = ( i_pos >> 24 ) & 0xff;    sctl_io.cdb[ 3 ] = ( i_pos >> 16 ) & 0xff;    sctl_io.cdb[ 4 ] = ( i_pos >>  8 ) & 0xff;    sctl_io.cdb[ 5 ] = ( i_pos       ) & 0xff;    sctl_io.cdb[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);    i_ret = ioctl( i_fd, SIOC_IO, &sctl_io );    memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );#elif defined( SOLARIS_USCSI )    INIT_USCSI( GPCMD_REPORT_KEY, 12 );    rs_cdb.cdb_opaque[ 2 ] = ( i_pos >> 24 ) & 0xff;    rs_cdb.cdb_opaque[ 3 ] = ( i_pos >> 16 ) & 0xff;    rs_cdb.cdb_opaque[ 4 ] = ( i_pos >>  8 ) & 0xff;    rs_cdb.cdb_opaque[ 5 ] = ( i_pos       ) & 0xff;    rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);    i_ret = SolarisSendUSCSI( i_fd, &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 );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?