--- bsdi_ioctl.c 2003-03-10 00:34:10.000000000 +0100 +++ bsdi_ioctl.c 2005-03-01 07:41:41.000000000 +0100 @@ -694,7 +698,7 @@ struct cdrom_tocentry entry; int ret, i; - bzero(tracks, sizeof (*tracks)); + memset(tracks, 0, sizeof (*tracks)); ret = cdrom_ioctl(fd, CDROMREADTOCHDR, &header); /* * This whole business is a crock anyhow so we don't bother distinguishing --- common.h 2003-06-13 19:33:35.000000000 +0200 +++ common.h 2005-03-01 07:41:41.000000000 +0100 @@ -27,21 +30,10 @@ /***************************************************************************** * Basic types definitions *****************************************************************************/ -#if defined( HAVE_STDINT_H ) -# include -#elif defined( HAVE_INTTYPES_H ) -# include -#elif defined( SYS_CYGWIN ) -# include - /* Cygwin only defines half of these... */ - typedef u_int8_t uint8_t; - typedef u_int32_t uint32_t; -#else - /* Fallback types (very x86-centric, sorry) */ - typedef unsigned char uint8_t; - typedef signed char int8_t; - typedef unsigned int uint32_t; - typedef signed int int32_t; +#include + +#ifdef __CYGWIN__ +#define SYS_CYGWIN #endif #if defined( WIN32 ) --- css.c 2003-07-29 01:37:06.000000000 +0200 +++ css.c 2005-03-01 07:41:41.000000000 +0100 @@ -40,19 +43,11 @@ #include #include #include -#ifdef HAVE_SYS_PARAM_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif #include +#include +#include -#ifdef HAVE_LIMITS_H -# include -#endif - -#include "dvdcss/dvdcss.h" +#include "dvdcss.h" #include "common.h" #include "css.h" --- device.c 2003-07-29 01:37:06.000000000 +0200 +++ device.c 2005-03-01 07:41:41.000000000 +0100 @@ -33,18 +36,9 @@ #include #include #include -#ifdef HAVE_SYS_PARAM_H -# include -#endif #include - -#ifdef HAVE_UNISTD_H -# include -#endif - -#ifdef HAVE_LIMITS_H -# include -#endif +#include +#include #if defined( WIN32 ) && !defined( SYS_CYGWIN ) # include /* read() */ @@ -52,7 +46,7 @@ # include /* struct iovec */ #endif -#include "dvdcss/dvdcss.h" +#include "dvdcss.h" #include "common.h" #include "css.h" @@ -143,8 +137,11 @@ _dvdcss_debug( dvdcss, psz_debug ); #if defined( WIN32 ) - /* If device is not "X:", we are actually opening a file. */ - dvdcss->b_file = !psz_device[0] || psz_device[1] != ':' || psz_device[2]; + 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; --- error.c 2003-03-10 01:15:31.000000000 +0100 +++ error.c 2005-03-01 07:41:41.000000000 +0100 @@ -25,16 +28,9 @@ #include #include +#include -#ifdef HAVE_SYS_PARAM_H -# include -#endif - -#ifdef HAVE_LIMITS_H -# include -#endif - -#include "dvdcss/dvdcss.h" +#include "dvdcss.h" #include "common.h" #include "css.h" --- ioctl.c 2003-03-10 00:34:10.000000000 +0100 +++ ioctl.c 2005-03-01 07:41:41.000000000 +0100 @@ -76,6 +79,7 @@ # include #endif #ifdef SOLARIS_USCSI +# include # include # include # include @@ -112,6 +116,7 @@ *****************************************************************************/ #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 /***************************************************************************** @@ -192,7 +197,7 @@ rs_cdb.cdb_opaque[ 6 ] = i_layer; rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_COPYRIGHT; - i_ret = ioctl(i_fd, USCSICMD, &sc); + i_ret = SolarisSendUSCSI(i_fd, &sc); if( i_ret < 0 || sc.uscsi_status ) { i_ret = -1; @@ -351,7 +356,7 @@ rs_cdb.cdb_opaque[ 7 ] = DVD_STRUCT_DISCKEY; rs_cdb.cdb_opaque[ 10 ] = *pi_agid << 6; - i_ret = ioctl( i_fd, USCSICMD, &sc ); + i_ret = SolarisSendUSCSI( i_fd, &sc ); if( i_ret < 0 || sc.uscsi_status ) { @@ -513,7 +518,7 @@ rs_cdb.cdb_opaque[ 5 ] = ( i_pos ) & 0xff; rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6); - i_ret = ioctl( i_fd, USCSICMD, &sc ); + i_ret = SolarisSendUSCSI( i_fd, &sc ); if( i_ret < 0 || sc.uscsi_status ) { @@ -665,7 +670,7 @@ rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6); - i_ret = ioctl( i_fd, USCSICMD, &sc ); + i_ret = SolarisSendUSCSI( i_fd, &sc ); if( i_ret < 0 || sc.uscsi_status ) { @@ -787,7 +792,7 @@ rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6); - i_ret = ioctl( i_fd, USCSICMD, &sc ); + i_ret = SolarisSendUSCSI( i_fd, &sc ); if( i_ret < 0 || sc.uscsi_status ) { @@ -921,7 +926,7 @@ rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_ASF; - i_ret = ioctl( i_fd, USCSICMD, &sc ); + i_ret = SolarisSendUSCSI( i_fd, &sc ); if( i_ret < 0 || sc.uscsi_status ) { @@ -1054,7 +1059,7 @@ rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6); - i_ret = ioctl( i_fd, USCSICMD, &sc ); + i_ret = SolarisSendUSCSI( i_fd, &sc ); if( i_ret < 0 || sc.uscsi_status ) { @@ -1175,7 +1180,7 @@ rs_cdb.cdb_opaque[ 10 ] = DVD_INVALIDATE_AGID | (*pi_agid << 6); - i_ret = ioctl( i_fd, USCSICMD, &sc ); + i_ret = SolarisSendUSCSI( i_fd, &sc ); if( i_ret < 0 || sc.uscsi_status ) { @@ -1299,7 +1304,7 @@ p_buffer[ 1 ] = 0xe; memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE ); - if( ioctl( i_fd, USCSICMD, &sc ) < 0 || sc.uscsi_status ) + if( SolarisSendUSCSI( i_fd, &sc ) < 0 || sc.uscsi_status ) { return -1; } @@ -1436,7 +1441,7 @@ p_buffer[ 1 ] = 0xa; memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE ); - if( ioctl( i_fd, USCSICMD, &sc ) < 0 || sc.uscsi_status ) + if( SolarisSendUSCSI( i_fd, &sc ) < 0 || sc.uscsi_status ) { return -1; } @@ -1578,7 +1583,7 @@ rs_cdb.cdb_opaque[ 10 ] = DVD_REPORT_RPC; - i_ret = ioctl( i_fd, USCSICMD, &sc ); + i_ret = SolarisSendUSCSI( i_fd, &sc ); if( i_ret < 0 || sc.uscsi_status ) { @@ -1728,7 +1733,7 @@ p_buffer[ 1 ] = 6; p_buffer[ 4 ] = i_pdrc; - i_ret = ioctl( i_fd, USCSICMD, &sc ); + i_ret = SolarisSendUSCSI( i_fd, &sc ); if( i_ret < 0 || sc.uscsi_status ) { @@ -1901,6 +1906,54 @@ 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 *sm_hdl; + static int initialized; + static void* (*sm_get_handle)(int32_t); + static int (*sm_release_handle)(void*); + static int (*sm_uscsi_cmd)(void*, struct uscsi_cmd *); + + if (!initialized) + { + void *smedia_lib; + + smedia_lib = dlopen("libsmedia.so", RTLD_NOW); + if (smedia_lib) { + sm_get_handle = dlsym(smedia_lib, "smedia_get_handle"); + sm_release_handle = dlsym(smedia_lib, "smedia_release_handle"); + sm_uscsi_cmd = dlsym(smedia_lib, "smedia_uscsi_cmd"); + } + initialized = 1; + } + + if (sm_get_handle && sm_uscsi_cmd && sm_release_handle + && (sm_hdl = sm_get_handle(i_fd))) + { + int i_ret = sm_uscsi_cmd(sm_hdl, p_sc); + sm_release_handle(sm_hdl); + return i_ret; + } + + return ioctl( i_fd, USCSICMD, p_sc ); +} #endif #if defined( WIN32 ) --- libdvdcss.c 2003-06-22 16:08:53.000000000 +0200 +++ libdvdcss.c 2005-03-01 07:41:41.000000000 +0100 @@ -22,7 +25,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ -/** +/* * \mainpage libdvdcss developer documentation * * \section intro Introduction @@ -87,10 +90,7 @@ * values. This will speed up descrambling of DVDs which are in the * cache. The DVDCSS_CACHE directory is created if it does not exist, * and a subdirectory is created named after the DVD's title or - * manufacturing date. If DVDCSS_CACHE is not set or is empty, \e libdvdcss - * will use the default value which is "${HOME}/.dvdcss/" under Unix and - * "C:\Documents and Settings\$USER\Application Data\dvdcss\" under Win32. - * The special value "off" disables caching. + * manufacturing date. */ /* @@ -103,28 +103,12 @@ #include #include #include -#ifdef HAVE_SYS_PARAM_H -# include -#endif -#ifdef HAVE_PWD_H -# include -#endif #include #include +#include +#include -#ifdef HAVE_UNISTD_H -# include -#endif - -#ifdef HAVE_LIMITS_H -# include -#endif - -#ifdef HAVE_DIRECT_H -# include -#endif - -#include "dvdcss/dvdcss.h" +#include "dvdcss.h" #include "common.h" #include "css.h" @@ -132,6 +116,12 @@ #include "ioctl.h" #include "device.h" +#ifndef HAVE_MPLAYER + #include "get_path.c" +#else + extern char * get_path( char * filename ); +#endif + /** * \brief Symbol for version checks. * @@ -234,87 +224,11 @@ } /* - * If DVDCSS_CACHE was not set, try to guess a default value - */ - if( psz_cache == NULL || psz_cache[0] == '\0' ) - { -#ifdef HAVE_DIRECT_H - typedef HRESULT( WINAPI *SHGETFOLDERPATH ) - ( HWND, int, HANDLE, DWORD, LPTSTR ); - -# define CSIDL_FLAG_CREATE 0x8000 -# define CSIDL_APPDATA 0x1A -# define SHGFP_TYPE_CURRENT 0 - - char psz_home[MAX_PATH]; - HINSTANCE p_dll; - SHGETFOLDERPATH p_getpath; - - *psz_home = '\0'; - - /* Load the shfolder dll to retrieve SHGetFolderPath */ - p_dll = LoadLibrary( "shfolder.dll" ); - if( p_dll ) - { - p_getpath = (void*)GetProcAddress( p_dll, "SHGetFolderPathA" ); - if( p_getpath ) - { - /* Get the "Application Data" folder for the current user */ - if( p_getpath( NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, - NULL, SHGFP_TYPE_CURRENT, psz_home ) == S_OK ) - { - FreeLibrary( p_dll ); - } - else - { - *psz_home = '\0'; - } - } - FreeLibrary( p_dll ); - } - - /* Cache our keys in - * C:\Documents and Settings\$USER\Application Data\dvdcss\ */ - if( *psz_home ) - { - snprintf( psz_buffer, PATH_MAX, "%s/dvdcss", psz_home ); - psz_buffer[PATH_MAX-1] = '\0'; - psz_cache = psz_buffer; - } -#else - char *psz_home = NULL; -# ifdef HAVE_PWD_H - struct passwd *p_pwd; - - /* Try looking in password file for home dir. */ - p_pwd = getpwuid(getuid()); - if( p_pwd ) - { - psz_home = p_pwd->pw_dir; - } -# endif - - if( psz_home == NULL ) - { - psz_home = getenv( "HOME" ); - } - - /* Cache our keys in ${HOME}/.dvdcss/ */ - if( psz_home ) - { - snprintf( psz_buffer, PATH_MAX, "%s/.dvdcss", psz_home ); - psz_buffer[PATH_MAX-1] = '\0'; - psz_cache = psz_buffer; - } -#endif - } - - /* * Find cache dir from the DVDCSS_CACHE environment variable */ if( psz_cache != NULL ) { - if( psz_cache[0] == '\0' || !strcmp( psz_cache, "off" ) ) + if( psz_cache[0] == '\0' ) { psz_cache = NULL; } @@ -325,6 +239,7 @@ psz_cache = NULL; } } + else psz_cache = get_path( "DVDKeys" ); /* * Open device @@ -465,9 +380,10 @@ dvdcss->psz_cachefile[0] = '\0'; goto nocache; } + i += sprintf( dvdcss->psz_cachefile + i, "/"); - i += sprintf( dvdcss->psz_cachefile + i, "/%s#%s", psz_title, - psz_serial ); +// i += sprintf( dvdcss->psz_cachefile + i, "/%s", psz_data ); + i += sprintf( dvdcss->psz_cachefile + i, "/%s#%s", psz_title, psz_serial ); #if !defined( WIN32 ) || defined( SYS_CYGWIN ) i_ret = mkdir( dvdcss->psz_cachefile, 0755 ); #else --- dvdcss/dvdcss.h 2003-04-18 20:05:36.000000000 +0200 +++ dvdcss.h 2005-03-01 07:41:41.000000000 +0100 @@ -67,6 +70,8 @@ */ extern dvdcss_t dvdcss_open ( char *psz_target ); extern int dvdcss_close ( dvdcss_t ); +extern int dvdcss_title ( dvdcss_t, + int i_block ); extern int dvdcss_seek ( dvdcss_t, int i_blocks, int i_flags );