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

📄 device.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 2 页
字号:
    dwSupportInfo = lpGetSupport();    if( HIBYTE( LOWORD ( dwSupportInfo ) ) == SS_NO_ADAPTERS )    {        print_error( dvdcss, "no ASPI adapters found" );        FreeLibrary( hASPI );        return -1;    }    if( HIBYTE( LOWORD ( dwSupportInfo ) ) != SS_COMP )    {        print_error( dvdcss, "unable to initalize aspi layer" );        FreeLibrary( hASPI );        return -1;    }    i_hostadapters = LOBYTE( LOWORD( dwSupportInfo ) );    if( i_hostadapters == 0 )    {        print_error( dvdcss, "no ASPI adapters ready" );        FreeLibrary( hASPI );        return -1;    }    fd = malloc( sizeof( struct w32_aspidev ) );    if( fd == NULL )    {        print_error( dvdcss, "not enough memory" );        FreeLibrary( hASPI );        return -1;    }    fd->i_blocks = 0;    fd->hASPI = (long) hASPI;    fd->lpSendCommand = lpSendCommand;    c_drive = c_drive > 'Z' ? c_drive - 'a' : c_drive - 'A';    for( i = 0; i < i_hostadapters; i++ )    {        for( j = 0; j < 15; j++ )        {            struct SRB_GetDiskInfo srbDiskInfo;            srbDiskInfo.SRB_Cmd         = SC_GET_DISK_INFO;            srbDiskInfo.SRB_HaId        = i;            srbDiskInfo.SRB_Flags       = 0;            srbDiskInfo.SRB_Hdr_Rsvd    = 0;            srbDiskInfo.SRB_Target      = j;            srbDiskInfo.SRB_Lun         = 0;            lpSendCommand( (void*) &srbDiskInfo );            if( (srbDiskInfo.SRB_Status == SS_COMP) &&                (srbDiskInfo.SRB_Int13HDriveInfo == c_drive) )            {                /* Make sure this is a cdrom device */                struct SRB_GDEVBlock srbGDEVBlock;                memset( &srbGDEVBlock, 0, sizeof(struct SRB_GDEVBlock) );                srbGDEVBlock.SRB_Cmd    = SC_GET_DEV_TYPE;                srbGDEVBlock.SRB_HaId   = i;                srbGDEVBlock.SRB_Target = j;                lpSendCommand( (void*) &srbGDEVBlock );                if( ( srbGDEVBlock.SRB_Status == SS_COMP ) &&                    ( srbGDEVBlock.SRB_DeviceType == DTYPE_CDROM ) )                {                    fd->i_sid = MAKEWORD( i, j );                    dvdcss->i_fd = (int) fd;                    dvdcss->i_pos = 0;                    return 0;                }                else                {                    free( (void*) fd );                    FreeLibrary( hASPI );                    print_error( dvdcss,"this is not a cdrom drive" );                    return -1;                }            }        }    }    free( (void*) fd );    FreeLibrary( hASPI );    print_error( dvdcss, "unable to get haid and target (aspi)" );    return -1;}#endif/***************************************************************************** * Seek commands. *****************************************************************************/static int libc_seek( dvdcss_t dvdcss, int i_blocks ){    off_t   i_seek;    if( dvdcss->i_pos == i_blocks )    {        /* We are already in position */        return i_blocks;    }    i_seek = (off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE;    i_seek = lseek( dvdcss->i_read_fd, i_seek, SEEK_SET );    if( i_seek < 0 )    {        print_error( dvdcss, "seek error" );        dvdcss->i_pos = -1;        return i_seek;    }    dvdcss->i_pos = i_seek / DVDCSS_BLOCK_SIZE;    return dvdcss->i_pos;}#if defined( WIN32 )static int win2k_seek( dvdcss_t dvdcss, int i_blocks ){    LARGE_INTEGER li_seek;#ifndef INVALID_SET_FILE_POINTER#   define INVALID_SET_FILE_POINTER ((DWORD)-1)#endif    if( dvdcss->i_pos == i_blocks )    {        /* We are already in position */        return i_blocks;    }    li_seek.QuadPart = (LONGLONG)i_blocks * DVDCSS_BLOCK_SIZE;    li_seek.LowPart = SetFilePointer( (HANDLE) dvdcss->i_fd,                                      li_seek.LowPart,                                      &li_seek.HighPart, FILE_BEGIN );    if( (li_seek.LowPart == INVALID_SET_FILE_POINTER)        && GetLastError() != NO_ERROR)    {        dvdcss->i_pos = -1;        return -1;    }    dvdcss->i_pos = li_seek.QuadPart / DVDCSS_BLOCK_SIZE;    return dvdcss->i_pos;}static int aspi_seek( dvdcss_t dvdcss, int i_blocks ){    int i_old_blocks;    char sz_buf[ DVDCSS_BLOCK_SIZE ];    struct w32_aspidev *fd = (struct w32_aspidev *) dvdcss->i_fd;    if( dvdcss->i_pos == i_blocks )    {        /* We are already in position */        return i_blocks;    }    i_old_blocks = fd->i_blocks;    fd->i_blocks = i_blocks;    if( aspi_read_internal( dvdcss->i_fd, sz_buf, 1 ) == -1 )    {        fd->i_blocks = i_old_blocks;        dvdcss->i_pos = -1;        return -1;    }    (fd->i_blocks)--;    dvdcss->i_pos = fd->i_blocks;    return dvdcss->i_pos;}#endif/***************************************************************************** * Read commands. *****************************************************************************/static int libc_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks ){    off_t i_size, i_ret;    i_size = (off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE;    i_ret = read( dvdcss->i_read_fd, p_buffer, i_size );    if( i_ret < 0 )    {        print_error( dvdcss, "read error" );        dvdcss->i_pos = -1;        return i_ret;    }    /* Handle partial reads */    if( i_ret != i_size )    {        int i_seek;        dvdcss->i_pos = -1;        i_seek = libc_seek( dvdcss, i_ret / DVDCSS_BLOCK_SIZE );        if( i_seek < 0 )        {            return i_seek;        }        /* We have to return now so that i_pos isn't clobbered */        return i_ret / DVDCSS_BLOCK_SIZE;    }    dvdcss->i_pos += i_ret / DVDCSS_BLOCK_SIZE;    return i_ret / DVDCSS_BLOCK_SIZE;}#if defined( WIN32 )static int win2k_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks ){    int i_bytes;    if( !ReadFile( (HANDLE) dvdcss->i_fd, p_buffer,              i_blocks * DVDCSS_BLOCK_SIZE,              (LPDWORD)&i_bytes, NULL ) )    {        dvdcss->i_pos = -1;        return -1;    }    dvdcss->i_pos += i_bytes / DVDCSS_BLOCK_SIZE;    return i_bytes / DVDCSS_BLOCK_SIZE;}static int aspi_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks ){    int i_read = aspi_read_internal( dvdcss->i_fd, p_buffer, i_blocks );    if( i_read < 0 )    {        dvdcss->i_pos = -1;        return i_read;    }    dvdcss->i_pos += i_read;    return i_read;}#endif/***************************************************************************** * Readv commands. *****************************************************************************/static int libc_readv ( dvdcss_t dvdcss, struct iovec *p_iovec, int i_blocks ){#if defined( WIN32 )    int i_index, i_len, i_total = 0;    unsigned char *p_base;    int i_bytes;    for( i_index = i_blocks;         i_index;         i_index--, p_iovec++ )    {        i_len  = p_iovec->iov_len;        p_base = p_iovec->iov_base;        if( i_len <= 0 )        {            continue;        }        i_bytes = read( dvdcss->i_fd, p_base, i_len );        if( i_bytes < 0 )        {            /* One of the reads failed, too bad.             * We won't even bother returning the reads that went ok,             * and as in the posix spec the file postition is left             * unspecified after a failure */            dvdcss->i_pos = -1;            return -1;        }        i_total += i_bytes;        if( i_bytes != i_len )        {            /* We reached the end of the file or a signal interrupted             * the read. Return a partial read. */            int i_seek;            dvdcss->i_pos = -1;            i_seek = libc_seek( dvdcss, i_total / DVDCSS_BLOCK_SIZE );            if( i_seek < 0 )            {                return i_seek;            }            /* We have to return now so that i_pos isn't clobbered */            return i_total / DVDCSS_BLOCK_SIZE;        }    }    dvdcss->i_pos += i_total / DVDCSS_BLOCK_SIZE;    return i_total / DVDCSS_BLOCK_SIZE;#else    int i_read = readv( dvdcss->i_read_fd, p_iovec, i_blocks );    if( i_read < 0 )    {        dvdcss->i_pos = -1;        return i_read;    }    dvdcss->i_pos += i_read / DVDCSS_BLOCK_SIZE;    return i_read / DVDCSS_BLOCK_SIZE;#endif}#if defined( WIN32 )/***************************************************************************** * win_readv: vectored read using ReadFile for Win2K and ASPI for win9x *****************************************************************************/static int win_readv ( dvdcss_t dvdcss, struct iovec *p_iovec, int i_blocks ){    int i_index;    int i_blocks_read, i_blocks_total = 0;    /* Check the size of the readv temp buffer, just in case we need to     * realloc something bigger */    if( dvdcss->i_readv_buf_size < i_blocks * DVDCSS_BLOCK_SIZE )    {        dvdcss->i_readv_buf_size = i_blocks * DVDCSS_BLOCK_SIZE;        if( dvdcss->p_readv_buffer ) free( dvdcss->p_readv_buffer );        /* Allocate a buffer which will be used as a temporary storage         * for readv */        dvdcss->p_readv_buffer = malloc( dvdcss->i_readv_buf_size );        if( !dvdcss->p_readv_buffer )        {            print_error( dvdcss, " failed (readv)" );            dvdcss->i_pos = -1;            return -1;        }    }    for( i_index = i_blocks; i_index; i_index-- )    {        i_blocks_total += p_iovec[i_index-1].iov_len;    }    if( i_blocks_total <= 0 ) return 0;    i_blocks_total /= DVDCSS_BLOCK_SIZE;    if( WIN2K )    {        unsigned long int i_bytes;        if( !ReadFile( (HANDLE)dvdcss->i_fd, dvdcss->p_readv_buffer,                       i_blocks_total * DVDCSS_BLOCK_SIZE, &i_bytes, NULL ) )        {            /* The read failed... too bad.             * As in the posix spec the file postition is left             * unspecified after a failure */            dvdcss->i_pos = -1;            return -1;        }        i_blocks_read = i_bytes / DVDCSS_BLOCK_SIZE;    }    else /* Win9x */    {        i_blocks_read = aspi_read_internal( dvdcss->i_fd,                                            dvdcss->p_readv_buffer,                                            i_blocks_total );        if( i_blocks_read < 0 )        {            /* See above */            dvdcss->i_pos = -1;            return -1;        }    }    /* We just have to copy the content of the temp buffer into the iovecs */    for( i_index = 0, i_blocks_total = i_blocks_read;         i_blocks_total > 0;         i_index++ )    {        memcpy( p_iovec[i_index].iov_base,                dvdcss->p_readv_buffer + (i_blocks_read - i_blocks_total)                                           * DVDCSS_BLOCK_SIZE,                p_iovec[i_index].iov_len );        /* if we read less blocks than asked, we'll just end up copying         * garbage, this isn't an issue as we return the number of         * blocks actually read */        i_blocks_total -= ( p_iovec[i_index].iov_len / DVDCSS_BLOCK_SIZE );    }    dvdcss->i_pos += i_blocks_read;    return i_blocks_read;}static int aspi_read_internal( int i_fd, void *p_data, int i_blocks ){    HANDLE hEvent;    struct SRB_ExecSCSICmd ssc;    struct w32_aspidev *fd = (struct w32_aspidev *) i_fd;    /* Create the transfer completion event */    hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );    if( hEvent == NULL )    {        return -1;    }    memset( &ssc, 0, sizeof( ssc ) );    ssc.SRB_Cmd         = SC_EXEC_SCSI_CMD;    ssc.SRB_Flags       = SRB_DIR_IN | SRB_EVENT_NOTIFY;    ssc.SRB_HaId        = LOBYTE( fd->i_sid );    ssc.SRB_Target      = HIBYTE( fd->i_sid );    ssc.SRB_SenseLen    = SENSE_LEN;    ssc.SRB_PostProc = (LPVOID) hEvent;    ssc.SRB_BufPointer  = p_data;    ssc.SRB_CDBLen      = 12;    ssc.CDBByte[0]      = 0xA8; /* RAW */    ssc.CDBByte[2]      = (UCHAR) (fd->i_blocks >> 24);    ssc.CDBByte[3]      = (UCHAR) (fd->i_blocks >> 16) & 0xff;    ssc.CDBByte[4]      = (UCHAR) (fd->i_blocks >> 8) & 0xff;    ssc.CDBByte[5]      = (UCHAR) (fd->i_blocks) & 0xff;    /* We have to break down the reads into 64kb pieces (ASPI restriction) */    if( i_blocks > 32 )    {        ssc.SRB_BufLen = 32 * DVDCSS_BLOCK_SIZE;        ssc.CDBByte[9] = 32;        fd->i_blocks  += 32;        /* Initiate transfer */        ResetEvent( hEvent );        fd->lpSendCommand( (void*) &ssc );        /* transfer the next 64kb (aspi_read_internal is called recursively)         * We need to check the status of the read on return */        if( aspi_read_internal( i_fd,                                (uint8_t*) p_data + 32 * DVDCSS_BLOCK_SIZE,                                i_blocks - 32) < 0 )        {            return -1;        }    }    else    {        /* This is the last transfer */        ssc.SRB_BufLen   = i_blocks * DVDCSS_BLOCK_SIZE;        ssc.CDBByte[9]   = (UCHAR) i_blocks;        fd->i_blocks += i_blocks;        /* Initiate transfer */        ResetEvent( hEvent );        fd->lpSendCommand( (void*) &ssc );    }    /* If the command has still not been processed, wait until it's finished */    if( ssc.SRB_Status == SS_PENDING )    {        WaitForSingleObject( hEvent, INFINITE );    }    CloseHandle( hEvent );    /* check that the transfer went as planned */    if( ssc.SRB_Status != SS_COMP )    {      return -1;    }    return i_blocks;}#endif

⌨️ 快捷键说明

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