⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 device.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * device.h: DVD device access ***************************************************************************** * Copyright (C) 1998-2006 VideoLAN * $Id: device.c,v 1.3 2008/04/12 07:14:44 dsqiu Exp $ * * Authors: St閜hane Borel <stef@via.ecp.fr> *          Sam Hocevar <sam@zoy.org> *          H錵an Hjort <d95hjort@dtek.chalmers.se> * * 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>#include <mplaylib.h>#ifdef HAVE_ERRNO_H#   include <errno.h>#endif#include <sys/types.h>#include <sys/stat.h>#ifdef HAVE_SYS_PARAM_H#   include <sys/param.h>#endif#include <fcntl.h>#ifdef HAVE_UNISTD_H#   include <unistd.h>#endif#ifdef HAVE_LIMITS_H#   include <limits.h>#endif#if defined( WIN32 ) && !defined( SYS_CYGWIN )#   include <io.h>                                                 /* read() */#else#   include <sys/uio.h>                                      /* struct iovec */#endif#ifdef DARWIN_DVD_IOCTL#   include <paths.h>#   include <CoreFoundation/CoreFoundation.h>#   include <IOKit/IOKitLib.h>#   include <IOKit/IOBSD.h>#   include <IOKit/storage/IOMedia.h>#   include <IOKit/storage/IOCDMedia.h>#   include <IOKit/storage/IODVDMedia.h>#endif#include "dvdcss/dvdcss.h"#include "common.h"#include "css.h"#include "libdvdcss.h"#include "ioctl.h"#include "device.h"#undef memcpy#define memcpy uc_memcpy/***************************************************************************** * Device reading prototypes *****************************************************************************/static int libc_open  ( dvdcss_t, char const * );static int libc_seek  ( dvdcss_t, int );static int libc_read  ( dvdcss_t, void *, int );static int libc_readv ( dvdcss_t, struct iovec *, int );#ifdef WIN32static int win2k_open ( dvdcss_t, char const * );static int aspi_open  ( dvdcss_t, char const * );static int win2k_seek ( dvdcss_t, int );static int aspi_seek  ( dvdcss_t, int );static int win2k_read ( dvdcss_t, void *, int );static int aspi_read  ( dvdcss_t, void *, int );static int win_readv  ( dvdcss_t, struct iovec *, int );static int aspi_read_internal  ( int, void *, int );#endifint _dvdcss_use_ioctls( dvdcss_t dvdcss ){#if defined( WIN32 )    if( dvdcss->b_file )    {        return 0;    }    /* FIXME: implement this for Windows */    if( WIN2K )    {        return 1;    }    else    {        return 1;    }#else    struct stat fileinfo;    int ret;    ret = fstat( dvdcss->i_fd, &fileinfo );    if( ret < 0 )    {        return 1;  /* What to do?  Be conservative and try to use the ioctls */    }    /* Complete this list and check that we test for the right things     * (I've assumed for all OSs that 'r', (raw) device, are char devices     *  and those that don't contain/use an 'r' in the name are block devices)     *     * Linux    needs a block device     * Solaris  needs a char device     * Darwin   needs a char device     * OpenBSD  needs a char device     * NetBSD   needs a char device     * FreeBSD  can use either the block or the char device     * BSD/OS   can use either the block or the char device     */    /* Check if this is a block/char device */    if( S_ISBLK( fileinfo.st_mode ) ||        S_ISCHR( fileinfo.st_mode ) )    {        return 1;    }    else    {        return 0;    }#endif}void _dvdcss_check ( dvdcss_t dvdcss ){#if defined( WIN32 )    DWORD drives;    int i;#elif defined( DARWIN_DVD_IOCTL )    io_object_t next_media;    mach_port_t master_port;    kern_return_t kern_result;    io_iterator_t media_iterator;    CFMutableDictionaryRef classes_to_match;#else    char *ppsz_devices[] = { "/dev/dvd", "/dev/cdrom", "/dev/hdc", NULL };    int i, i_fd;#endif    /* If the device name is non-null, return */    if( dvdcss->psz_device[0] )    {        return;    }#if defined( WIN32 )    drives = GetLogicalDrives();    for( i = 0; drives; i++ )    {        char psz_device[5];        DWORD cur = 1 << i;        UINT i_ret;        if( (drives & cur) == 0 )        {            continue;        }        drives &= ~cur;        sprintf( psz_device, "%c:\\", 'A' + i );        i_ret = GetDriveType( psz_device );        if( i_ret != DRIVE_CDROM )        {            continue;        }        /* Remove trailing backslash */        psz_device[2] = '\0';        /* FIXME: we want to differenciate between CD and DVD drives         * using DeviceIoControl() */        print_debug( dvdcss, "defaulting to drive `%s'", psz_device );        free( dvdcss->psz_device );        dvdcss->psz_device = strdup( psz_device );        return;    }#elif defined( DARWIN_DVD_IOCTL )    kern_result = IOMasterPort( MACH_PORT_NULL, &master_port );    if( kern_result != KERN_SUCCESS )    {        return;    }    classes_to_match = IOServiceMatching( kIODVDMediaClass );    if( classes_to_match == NULL )    {        return;    }    CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ),                          kCFBooleanTrue );    kern_result = IOServiceGetMatchingServices( master_port, classes_to_match,                                                &media_iterator );    if( kern_result != KERN_SUCCESS )    {        return;    }    next_media = IOIteratorNext( media_iterator );    for( ; ; )    {        char psz_buf[0x32];        size_t i_pathlen;        CFTypeRef psz_path;        next_media = IOIteratorNext( media_iterator );        if( next_media == 0 )        {            break;        }        psz_path = IORegistryEntryCreateCFProperty( next_media,                                                    CFSTR( kIOBSDNameKey ),                                                    kCFAllocatorDefault,                                                    0 );        if( psz_path == NULL )        {            IOObjectRelease( next_media );            continue;        }        snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' );        i_pathlen = strlen( psz_buf );        if( CFStringGetCString( psz_path,                                (char*)&psz_buf + i_pathlen,                                sizeof(psz_buf) - i_pathlen,                                kCFStringEncodingASCII ) )        {            print_debug( dvdcss, "defaulting to drive `%s'", psz_buf );            CFRelease( psz_path );            IOObjectRelease( next_media );            IOObjectRelease( media_iterator );            free( dvdcss->psz_device );            dvdcss->psz_device = strdup( psz_buf );            return;        }        CFRelease( psz_path );        IOObjectRelease( next_media );    }    IOObjectRelease( media_iterator );#else    for( i = 0; ppsz_devices[i]; i++ )    {        i_fd = open( ppsz_devices[i], 0 );        if( i_fd != -1 )        {            print_debug( dvdcss, "defaulting to drive `%s'", ppsz_devices[i] );            close( i_fd );            free( dvdcss->psz_device );            dvdcss->psz_device = strdup( ppsz_devices[i] );            return;        }    }#endif    print_error( dvdcss, "could not find a suitable default drive" );}int _dvdcss_open ( dvdcss_t dvdcss ){    char const *psz_device = dvdcss->psz_device;    print_debug( dvdcss, "opening target `%s'", psz_device );#if defined( WIN32 )    dvdcss->b_file = 1;    /* If device is "X:" or "X:\", we are not actually opening a file. */    if (psz_device[0] && psz_device[1] == ':' &&       (!psz_device[2] || (psz_device[2] == '\\' && !psz_device[3])))        dvdcss->b_file = 0;    /* Initialize readv temporary buffer */    dvdcss->p_readv_buffer   = NULL;    dvdcss->i_readv_buf_size = 0;    if( !dvdcss->b_file && WIN2K )    {        print_debug( dvdcss, "using Win2K API for access" );        dvdcss->pf_seek  = win2k_seek;        dvdcss->pf_read  = win2k_read;        dvdcss->pf_readv = win_readv;        return win2k_open( dvdcss, psz_device );    }    else if( !dvdcss->b_file )    {        print_debug( dvdcss, "using ASPI for access" );        dvdcss->pf_seek  = aspi_seek;        dvdcss->pf_read  = aspi_read;        dvdcss->pf_readv = win_readv;        return aspi_open( dvdcss, psz_device );    }    else#endif    {        print_debug( dvdcss, "using libc for access" );        dvdcss->pf_seek  = libc_seek;        dvdcss->pf_read  = libc_read;        dvdcss->pf_readv = libc_readv;        return libc_open( dvdcss, psz_device );    }}#ifndef WIN32int _dvdcss_raw_open ( dvdcss_t dvdcss, char const *psz_device ){    dvdcss->i_raw_fd = open( psz_device, 0 );    if( dvdcss->i_raw_fd == -1 )    {        print_debug( dvdcss, "cannot open %s (%s)",                             psz_device, strerror(errno) );        print_error( dvdcss, "failed to open raw device, but continuing" );        return -1;    }    else    {        dvdcss->i_read_fd = dvdcss->i_raw_fd;    }    return 0;}#endifint _dvdcss_close ( dvdcss_t dvdcss ){#if defined( WIN32 )    if( dvdcss->b_file )    {        close( dvdcss->i_fd );    }    else if( WIN2K )    {        CloseHandle( (HANDLE) dvdcss->i_fd );    }    else /* ASPI */    {        struct w32_aspidev *fd = (struct w32_aspidev *) dvdcss->i_fd;        /* Unload aspi and free w32_aspidev structure */        FreeLibrary( (HMODULE) fd->hASPI );        free( (void*) dvdcss->i_fd );    }    /* Free readv temporary buffer */    if( dvdcss->p_readv_buffer )    {        free( dvdcss->p_readv_buffer );        dvdcss->p_readv_buffer   = NULL;        dvdcss->i_readv_buf_size = 0;    }    return 0;#else    close( dvdcss->i_fd );    if( dvdcss->i_raw_fd >= 0 )    {        close( dvdcss->i_raw_fd );        dvdcss->i_raw_fd = -1;    }    return 0;#endif}/* Following functions are local *//***************************************************************************** * Open commands. *****************************************************************************/static int libc_open ( dvdcss_t dvdcss, char const *psz_device ){#if !defined( WIN32 )    dvdcss->i_fd = dvdcss->i_read_fd = open( psz_device, 0 );#else    dvdcss->i_fd = dvdcss->i_read_fd = open( psz_device, O_BINARY );#endif    if( dvdcss->i_fd == -1 )    {        print_debug( dvdcss, "cannot open %s (%s)",                             psz_device, strerror(errno) );        print_error( dvdcss, "failed to open device" );        return -1;    }    dvdcss->i_pos = 0;    return 0;}#if defined( WIN32 )static int win2k_open ( dvdcss_t dvdcss, char const *psz_device ){    char psz_dvd[7];    _snprintf( psz_dvd, 7, "\\\\.\\%c:", psz_device[0] );    /* To work around an M$ bug in IOCTL_DVD_READ_STRUCTURE, we need read     * _and_ write access to the device (so we can make SCSI Pass Through     * Requests). Unfortunately this is only allowed if you have     * administrator priviledges so we allow for a fallback method with     * only read access to the device (in this case ioctl_ReadCopyright()     * won't send back the right result).     * (See Microsoft Q241374: Read and Write Access Required for SCSI     * Pass Through Requests) */    dvdcss->i_fd = (int)                CreateFile( psz_dvd, GENERIC_READ | GENERIC_WRITE,                            FILE_SHARE_READ | FILE_SHARE_WRITE,                            NULL, OPEN_EXISTING,                            FILE_FLAG_RANDOM_ACCESS, NULL );    if( (HANDLE) dvdcss->i_fd == INVALID_HANDLE_VALUE )        dvdcss->i_fd = (int)                    CreateFile( psz_dvd, GENERIC_READ, FILE_SHARE_READ,                                NULL, OPEN_EXISTING,                                FILE_FLAG_RANDOM_ACCESS, NULL );    if( (HANDLE) dvdcss->i_fd == INVALID_HANDLE_VALUE )    {        print_error( dvdcss, "failed opening device" );        return -1;    }    dvdcss->i_pos = 0;    return 0;}static int aspi_open( dvdcss_t dvdcss, char const * psz_device ){    HMODULE hASPI;    DWORD dwSupportInfo;    struct w32_aspidev *fd;    int i, j, i_hostadapters;    GETASPI32SUPPORTINFO lpGetSupport;    SENDASPI32COMMAND lpSendCommand;    char c_drive = psz_device[0];    /* load aspi and init w32_aspidev structure */    hASPI = LoadLibrary( "wnaspi32.dll" );    if( hASPI == NULL )    {        print_error( dvdcss, "unable to load wnaspi32.dll" );        return -1;    }    lpGetSupport = (GETASPI32SUPPORTINFO) GetProcAddress( hASPI, "GetASPI32SupportInfo" );    lpSendCommand = (SENDASPI32COMMAND) GetProcAddress( hASPI, "SendASPI32Command" );    if(lpGetSupport == NULL || lpSendCommand == NULL )    {        print_error( dvdcss, "unable to get aspi function pointers" );        FreeLibrary( hASPI );        return -1;    }

⌨️ 快捷键说明

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