Commit 52add4b0 authored by Gildas Bazin's avatar Gildas Bazin

- Removed unecessary translations in the win32 code from block offsets to
    byte offsets. This was overflowing some variables.
- Reduced the complexity of the Win9x ASPI functions because we only need
    to handle DVD drive access.
- Win32 code now handles seeking in areas above 2.1 Go on DVDs.
parent f58cb69a
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* css.c: Functions for DVD authentification and unscrambling * css.c: Functions for DVD authentification and unscrambling
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: css.c,v 1.3 2001/06/29 11:34:28 stef Exp $ * $Id: css.c,v 1.4 2001/07/07 21:10:58 gbazin Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -37,12 +37,6 @@ ...@@ -37,12 +37,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#elif defined( WIN32 )
# include <io.h>
#endif
#include <string.h> #include <string.h>
#include "config.h" #include "config.h"
...@@ -321,7 +315,7 @@ int CSSGetKey( dvdcss_handle dvdcss ) ...@@ -321,7 +315,7 @@ int CSSGetKey( dvdcss_handle dvdcss )
*/ */
u8 pi_buf[0x800]; u8 pi_buf[0x800];
dvd_key_t pi_key; dvd_key_t pi_key;
off_t i_pos; int i_pos;
boolean_t b_encrypted; boolean_t b_encrypted;
boolean_t b_stop_scanning; boolean_t b_stop_scanning;
int i_blocks_read; int i_blocks_read;
...@@ -338,7 +332,7 @@ int CSSGetKey( dvdcss_handle dvdcss ) ...@@ -338,7 +332,7 @@ int CSSGetKey( dvdcss_handle dvdcss )
b_stop_scanning = 0; b_stop_scanning = 0;
/* Position of the title on the disc */ /* Position of the title on the disc */
i_pos = (off_t)dvdcss->css.i_title_pos; i_pos = dvdcss->css.i_title_pos;
do { do {
i_pos = dvdcss_seek( dvdcss, i_pos ); i_pos = dvdcss_seek( dvdcss, i_pos );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* css.h: Structures for DVD authentification and unscrambling * css.h: Structures for DVD authentification and unscrambling
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: css.h,v 1.2 2001/06/20 07:43:48 sam Exp $ * $Id: css.h,v 1.3 2001/07/07 21:10:58 gbazin Exp $
* *
* Author: Stphane Borel <stef@via.ecp.fr> * Author: Stphane Borel <stef@via.ecp.fr>
* *
...@@ -51,7 +51,7 @@ typedef struct css_s ...@@ -51,7 +51,7 @@ typedef struct css_s
disc_t disc; disc_t disc;
u8 pi_disc_key[2048]; u8 pi_disc_key[2048];
int i_title; int i_title;
off_t i_title_pos; int i_title_pos;
dvd_key_t pi_title_key; dvd_key_t pi_title_key;
} css_t; } css_t;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ioctl.h: DVD ioctl replacement function * ioctl.h: DVD ioctl replacement function
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: ioctl.h,v 1.4 2001/06/25 11:34:08 sam Exp $ * $Id: ioctl.h,v 1.5 2001/07/07 21:10:58 gbazin Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -192,10 +192,10 @@ typedef struct _SCSI_PASS_THROUGH_DIRECT ...@@ -192,10 +192,10 @@ typedef struct _SCSI_PASS_THROUGH_DIRECT
struct w32_aspidev struct w32_aspidev
{ {
long hASPI; long hASPI;
short i_sid; short i_sid;
off_t i_pos; int i_blocks;
long (*lpSendCommand)( void* ); long (*lpSendCommand)( void* );
}; };
#pragma pack(1) #pragma pack(1)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libdvdcss.c: DVD reading library. * libdvdcss.c: DVD reading library.
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: libdvdcss.c,v 1.3 2001/06/14 02:47:44 sam Exp $ * $Id: libdvdcss.c,v 1.4 2001/07/07 21:10:58 gbazin Exp $
* *
* Authors: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -64,12 +64,12 @@ static int _dvdcss_readv ( dvdcss_handle, struct iovec *p_iovec, int i_blocks ); ...@@ -64,12 +64,12 @@ static int _dvdcss_readv ( dvdcss_handle, struct iovec *p_iovec, int i_blocks );
* Local prototypes, win32 specific * Local prototypes, win32 specific
*****************************************************************************/ *****************************************************************************/
#if defined( WIN32 ) #if defined( WIN32 )
static int _win32_readv ( int i_fd, struct iovec *p_iovec, int i_blocks ); static int _win32_dvdcss_readv ( int i_fd, struct iovec *p_iovec,
static int _win32_aopen ( char c_drive, dvdcss_handle dvdcss ); int i_num_buffers );
static int _win32_aclose ( int i_fd ); static int _win32_dvdcss_aopen ( char c_drive, dvdcss_handle dvdcss );
static int _win32_aseek ( int i_fd, off_t i_pos, int i_method ); static int _win32_dvdcss_aclose ( int i_fd );
static int _win32_aread ( int i_fd, void *p_data, int i_len ); static int _win32_dvdcss_aseek ( int i_fd, int i_blocks, int i_method );
static int _win32_areadv ( int i_fd, struct iovec *p_iovec, int i_blocks ); static int _win32_dvdcss_aread ( int i_fd, void *p_data, int i_blocks );
#endif #endif
/***************************************************************************** /*****************************************************************************
...@@ -302,7 +302,7 @@ static int _dvdcss_open ( dvdcss_handle dvdcss, char *psz_target ) ...@@ -302,7 +302,7 @@ static int _dvdcss_open ( dvdcss_handle dvdcss, char *psz_target )
} }
else else
{ {
dvdcss->i_fd = _win32_aopen( psz_target[0], dvdcss ); dvdcss->i_fd = _win32_dvdcss_aopen( psz_target[0], dvdcss );
if( dvdcss->i_fd == -1 ) if( dvdcss->i_fd == -1 )
{ {
_dvdcss_error( dvdcss, "failed opening device" ); _dvdcss_error( dvdcss, "failed opening device" );
...@@ -333,7 +333,7 @@ static int _dvdcss_close ( dvdcss_handle dvdcss ) ...@@ -333,7 +333,7 @@ static int _dvdcss_close ( dvdcss_handle dvdcss )
} }
else else
{ {
_win32_aclose( dvdcss->i_fd ); _win32_dvdcss_aclose( dvdcss->i_fd );
} }
#else #else
close( dvdcss->i_fd ); close( dvdcss->i_fd );
...@@ -344,128 +344,136 @@ static int _dvdcss_close ( dvdcss_handle dvdcss ) ...@@ -344,128 +344,136 @@ static int _dvdcss_close ( dvdcss_handle dvdcss )
static int _dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks ) static int _dvdcss_seek ( dvdcss_handle dvdcss, int i_blocks )
{ {
off_t i_read;
#if defined( WIN32 ) #if defined( WIN32 )
if( WIN2K ) if( WIN2K )
{ {
i_read = SetFilePointer( (HANDLE) dvdcss->i_fd, LARGE_INTEGER li_read;
(off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE,
NULL, FILE_BEGIN ); #ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
#endif
li_read.QuadPart = (LONGLONG)i_blocks * DVDCSS_BLOCK_SIZE;
li_read.LowPart = SetFilePointer( (HANDLE) dvdcss->i_fd,
li_read.LowPart,
&li_read.HighPart, FILE_BEGIN );
if( (li_read.LowPart == INVALID_SET_FILE_POINTER)
&& GetLastError() != NO_ERROR)
{
li_read.QuadPart = -DVDCSS_BLOCK_SIZE;
}
li_read.QuadPart /= DVDCSS_BLOCK_SIZE;
return (int)li_read.QuadPart;
} }
else else
{ {
i_read = _win32_aseek( dvdcss->i_fd, return ( _win32_dvdcss_aseek( dvdcss->i_fd, i_blocks, SEEK_SET ) );
(off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE, SEEK_SET );
} }
#else #else
off_t i_read;
i_read = lseek( dvdcss->i_fd, i_read = lseek( dvdcss->i_fd,
(off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE, SEEK_SET ); (off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE, SEEK_SET );
return i_read / DVDCSS_BLOCK_SIZE;
#endif #endif
return i_read / DVDCSS_BLOCK_SIZE;
} }
static int _dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, int i_blocks ) static int _dvdcss_read ( dvdcss_handle dvdcss, void *p_buffer, int i_blocks )
{ {
off_t i_read; int i_read;
#if defined( WIN32 ) #if defined( WIN32 )
if( WIN2K ) if( WIN2K )
{ {
if( ReadFile( (HANDLE) dvdcss->i_fd, p_buffer, if( !ReadFile( (HANDLE) dvdcss->i_fd, p_buffer,
(off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE, i_blocks * DVDCSS_BLOCK_SIZE,
&i_read, NULL ) == -1 ) (LPDWORD)&i_read, NULL ) )
{ {
return 0; i_read = -DVDCSS_BLOCK_SIZE;
} }
return i_read / DVDCSS_BLOCK_SIZE;
} }
else else
{ {
i_read = _win32_aread( dvdcss->i_fd, p_buffer, i_read = _win32_dvdcss_aread( dvdcss->i_fd, p_buffer, i_blocks );
(off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE ); return i_read;
} }
#else #else
i_read = read( dvdcss->i_fd, p_buffer, i_read = read( dvdcss->i_fd, p_buffer, (size_t)i_blocks * DVDCSS_BLOCK_SIZE );
(off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE ); return i_read / DVDCSS_BLOCK_SIZE;
#endif #endif
return i_read / DVDCSS_BLOCK_SIZE;
} }
static int _dvdcss_readv ( dvdcss_handle dvdcss, struct iovec *p_iovec, int i_blocks ) static int _dvdcss_readv ( dvdcss_handle dvdcss, struct iovec *p_iovec, int i_blocks )
{ {
off_t i_read; int i_read;
#if defined( WIN32 ) #if defined( WIN32 )
if( WIN2K ) i_read = _win32_dvdcss_readv( dvdcss->i_fd, p_iovec, i_blocks );
{ return i_read;
i_read = _win32_readv( dvdcss->i_fd, p_iovec, i_blocks );
}
else
{
i_read = _win32_areadv( dvdcss->i_fd, p_iovec, i_blocks );
}
#else #else
i_read = readv( dvdcss->i_fd, p_iovec, i_blocks ); i_read = readv( dvdcss->i_fd, p_iovec, i_blocks );
#endif
return i_read / DVDCSS_BLOCK_SIZE; return i_read / DVDCSS_BLOCK_SIZE;
#endif
} }
#if defined( WIN32 ) #if defined( WIN32 )
/***************************************************************************** /*****************************************************************************
* _win32_readv: vectored read using ReadFile instead of read * _win32_dvdcss_readv: vectored read using ReadFile for Win2K and
* _win32_dvdcss_aread for win9x
*****************************************************************************/ *****************************************************************************/
static int _win32_readv( int i_fd, struct iovec *p_iovec, int i_blocks ) static int _win32_dvdcss_readv( int i_fd, struct iovec *p_iovec,
int i_num_buffers )
{ {
int i_index, i_len, i_total = 0; int i_index, i_len, i_total = 0;
char *p_base; char *p_base;
int i_blocks;
for( i_index = i_blocks; i_index; i_index-- ) for( i_index = i_num_buffers; i_index; i_index-- )
{ {
unsigned long i_bytes;
i_len = p_iovec->iov_len; i_len = p_iovec->iov_len;
p_base = p_iovec->iov_base; p_base = p_iovec->iov_base;
/* Loop is unrolled one time to spare the (i_bytes < 0) test */
if( i_len > 0 ) if( i_len > 0 )
{ {
if( !ReadFile( (HANDLE) i_fd, p_base, i_len, &i_bytes, NULL ) ) if( WIN2K )
{ {
i_bytes = -1; unsigned long int i_bytes;
if( !ReadFile( (HANDLE) i_fd, p_base, i_len, &i_bytes, NULL ) )
{
return -1;
/* One of the reads failed, too bad.
We won't even bother returning the reads that went well,
and like in the posix spec the file postition is left
unspecified after a failure */
}
i_blocks = i_bytes / DVDCSS_BLOCK_SIZE;
} }
else /* Win9x */
if( ( i_total == 0 ) && ( i_bytes < 0 ) )
{ {
return -1; i_blocks = _win32_dvdcss_aread( i_fd, p_base, i_len );
if( i_blocks < 0 )
{
return -1; /* idem */
}
} }
if( i_bytes <= 0 ) if( i_blocks != (i_len / DVDCSS_BLOCK_SIZE) )
{ {
/* we reached the end of the file */
return i_total; return i_total;
} }
i_len -= i_bytes; i_total += i_blocks;
i_total += i_bytes;
p_base += i_bytes;
while( i_len > 0 )
{
if( !ReadFile( (HANDLE) i_fd, p_base, i_len, &i_bytes, NULL ) )
{
return i_total;
}
i_len -= i_bytes;
i_total += i_bytes;
p_base += i_bytes;
}
} }
p_iovec++; p_iovec++;
...@@ -475,9 +483,10 @@ static int _win32_readv( int i_fd, struct iovec *p_iovec, int i_blocks ) ...@@ -475,9 +483,10 @@ static int _win32_readv( int i_fd, struct iovec *p_iovec, int i_blocks )
} }
/***************************************************************************** /*****************************************************************************
* _win32_aopen: open dvd drive (load aspi and init w32_aspidev structure) * _win32_dvdcss_aopen: open dvd drive (load aspi and init w32_aspidev
* structure)
*****************************************************************************/ *****************************************************************************/
static int _win32_aopen( char c_drive, dvdcss_handle dvdcss ) static int _win32_dvdcss_aopen( char c_drive, dvdcss_handle dvdcss )
{ {
HMODULE hASPI; HMODULE hASPI;
DWORD dwSupportInfo; DWORD dwSupportInfo;
...@@ -533,7 +542,7 @@ static int _win32_aopen( char c_drive, dvdcss_handle dvdcss ) ...@@ -533,7 +542,7 @@ static int _win32_aopen( char c_drive, dvdcss_handle dvdcss )
return -1; return -1;
} }
fd->i_pos = 0; fd->i_blocks = 0;
fd->hASPI = (long) hASPI; fd->hASPI = (long) hASPI;
fd->lpSendCommand = lpSendCommand; fd->lpSendCommand = lpSendCommand;
...@@ -577,9 +586,10 @@ static int _win32_aopen( char c_drive, dvdcss_handle dvdcss ) ...@@ -577,9 +586,10 @@ static int _win32_aopen( char c_drive, dvdcss_handle dvdcss )
} }
/***************************************************************************** /*****************************************************************************
* _win32_aclose: close dvd drive (unload aspi and free w32_aspidev structure) * _win32_dvdcss_aclose: close dvd drive (unload aspi and free w32_aspidev
* structure)
*****************************************************************************/ *****************************************************************************/
static int _win32_aclose( int i_fd ) static int _win32_dvdcss_aclose( int i_fd )
{ {
struct w32_aspidev *fd = (struct w32_aspidev *) i_fd; struct w32_aspidev *fd = (struct w32_aspidev *) i_fd;
...@@ -590,61 +600,50 @@ static int _win32_aclose( int i_fd ) ...@@ -590,61 +600,50 @@ static int _win32_aclose( int i_fd )
} }
/***************************************************************************** /*****************************************************************************
* _win32_aseek: aspi version of lseek * _win32_dvdcss_aseek: aspi version of _dvdcss_seek
*
* returns the number of blocks read.
*****************************************************************************/ *****************************************************************************/
static int _win32_aseek( int i_fd, off_t i_pos, int i_method ) static int _win32_dvdcss_aseek( int i_fd, int i_blocks, int i_method )
{ {
int i_oldpos; int i_old_blocks;
char sz_buf[ 2048 ]; char sz_buf[ DVDCSS_BLOCK_SIZE ];
struct w32_aspidev *fd = (struct w32_aspidev *) i_fd; struct w32_aspidev *fd = (struct w32_aspidev *) i_fd;
i_oldpos = fd->i_pos; i_old_blocks = fd->i_blocks;
fd->i_pos = i_pos; fd->i_blocks = i_blocks;
if( _win32_aread( i_fd, sz_buf, sizeof(sz_buf) ) == -1 ) if( _win32_dvdcss_aread( i_fd, sz_buf, 1 ) == -1 )
{ {
fd->i_pos = i_oldpos; fd->i_blocks = i_old_blocks;
return -1; return -1;
} }
fd->i_pos -= sizeof(sz_buf); (fd->i_blocks)--;
return fd->i_pos; return fd->i_blocks;
} }
/***************************************************************************** /*****************************************************************************
* _win32_aread: aspi version of read * _win32_dvdcss_aread: aspi version of _dvdcss_read
*
* returns the number of blocks read.
*****************************************************************************/ *****************************************************************************/
static int _win32_aread( int i_fd, void *p_data, int i_len ) static int _win32_dvdcss_aread( int i_fd, void *p_data, int i_blocks )
{ {
HANDLE hEvent; HANDLE hEvent;
char *p_buf = NULL;
DWORD dwStart, dwLen; DWORD dwStart, dwLen;
struct SRB_ExecSCSICmd ssc; struct SRB_ExecSCSICmd ssc;
struct w32_aspidev *fd = (struct w32_aspidev *) i_fd; struct w32_aspidev *fd = (struct w32_aspidev *) i_fd;
memset( &ssc, 0, sizeof( ssc ) ); memset( &ssc, 0, sizeof( ssc ) );
dwStart = fd->i_pos / 2048; dwStart = fd->i_blocks;
dwLen = ( i_len % 2048 ? ( i_len / 2048 ) + 1 : ( i_len / 2048 ) ) + dwLen = i_blocks;
(int)( fd->i_pos % 2048 ? 1 : 0 );
if( fd->i_pos % 2048 || i_len % 2048 )
{
p_buf = malloc( dwLen * 2048 );
if( p_buf == NULL )
{
return -1;
}
}
hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if( hEvent == NULL ) if( hEvent == NULL )
{ {
if( p_buf != NULL )
{
free( p_buf );
}
return -1; return -1;
} }
...@@ -655,8 +654,8 @@ static int _win32_aread( int i_fd, void *p_data, int i_len ) ...@@ -655,8 +654,8 @@ static int _win32_aread( int i_fd, void *p_data, int i_len )
ssc.SRB_SenseLen = SENSE_LEN; ssc.SRB_SenseLen = SENSE_LEN;
ssc.SRB_PostProc = (LPVOID) hEvent; ssc.SRB_PostProc = (LPVOID) hEvent;
ssc.SRB_BufLen = dwLen * 2048; ssc.SRB_BufLen = dwLen * DVDCSS_BLOCK_SIZE;
ssc.SRB_BufPointer = p_buf ? p_buf : p_data; ssc.SRB_BufPointer = p_data;
ssc.SRB_CDBLen = 12; ssc.SRB_CDBLen = 12;
ssc.CDBByte[0] = 0xA8; /* RAW */ ssc.CDBByte[0] = 0xA8; /* RAW */
...@@ -675,75 +674,14 @@ static int _win32_aread( int i_fd, void *p_data, int i_len ) ...@@ -675,75 +674,14 @@ static int _win32_aread( int i_fd, void *p_data, int i_len )
CloseHandle( hEvent ); CloseHandle( hEvent );
if( p_buf != NULL )
{
memcpy( p_data, p_buf + ( fd->i_pos - ( dwStart * 2048 ) ), i_len );
free( p_buf );
}
if(ssc.SRB_Status != SS_COMP) if(ssc.SRB_Status != SS_COMP)
{ {
return -1;
}
fd->i_pos += i_len;
return i_len;
}
/*****************************************************************************
* _win32_areadv: aspi version of readv
*****************************************************************************/
static int _win32_areadv( int i_fd, struct iovec *p_iovec, int i_blocks )
{
int i_index, i_len, i_total = 0;
char *p_base;
for( i_index = i_blocks; i_index; i_index-- )
{
register signed int i_bytes;
i_len = p_iovec->iov_len;
p_base = p_iovec->iov_base;
/* Loop is unrolled one time to spare the (i_bytes < 0) test */
if( i_len > 0 )
{
i_bytes = _win32_aread( i_fd, p_base, i_len );
if( ( i_total == 0 ) && ( i_bytes < 0 ) )
{
return -1; return -1;
}
if( i_bytes <= 0 )
{
return i_total;
}
i_len -= i_bytes;
i_total += i_bytes;
p_base += i_bytes;
while( i_len > 0 )
{
i_bytes = _win32_aread( i_fd, p_base, i_len );
if( i_bytes <= 0 )
{
return i_total;
}
i_len -= i_bytes;
i_total += i_bytes;
p_base += i_bytes;
}
}
p_iovec++;
} }
fd->i_blocks += i_blocks;
return i_total; return i_blocks;
} }
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment