├── cmake ├── dvdcss-config.cmake ├── CheckFileOffsetBits.c └── CheckFileOffsetBits.cmake ├── src ├── libdvdcss.pc.in ├── dvdcss │ ├── version.h.in │ └── dvdcss.h ├── device.h ├── error.c ├── css.h ├── common.h ├── libdvdcss.h ├── ioctl.h ├── csstables.h ├── libdvdcss.c └── device.c ├── .gitignore ├── msvc ├── workspace.dsw ├── config.h ├── uwpapi.cpp ├── libdvdcss.dsp ├── csstest.dsp └── libdvdcss.vcxproj ├── INSTALL ├── .gitlab-ci.yml ├── AUTHORS ├── Makefile.am ├── README.md ├── test ├── csstest.c └── dvd_region.c ├── config.h.cm ├── NEWS ├── CMakeLists.txt ├── libdvdcss.spec.in ├── configure.ac ├── m4 └── attributes.m4 └── COPYING /cmake/dvdcss-config.cmake: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/dvdcss.cmake) 2 | -------------------------------------------------------------------------------- /src/libdvdcss.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libdvdcss 7 | Description: DVD access and decryption library. 8 | Version: @VERSION@ 9 | Libs: -L${libdir} -ldvdcss 10 | Cflags: -I${includedir} -I${includedir}/dvdcss 11 | -------------------------------------------------------------------------------- /cmake/CheckFileOffsetBits.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define KB ((off_t)1024) 4 | #define MB ((off_t)1024 * KB) 5 | #define GB ((off_t)1024 * MB) 6 | #define TB ((off_t)1024 * GB) 7 | int t2[(((64 * GB -1) % 671088649) == 268434537) 8 | && (((TB - (64 * GB -1) + 255) % 1792151290) == 305159546)? 1: -1]; 9 | 10 | int main() 11 | { 12 | ; 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.libs 2 | /ChangeLog 3 | /Makefile 4 | /Makefile.in 5 | /aclocal.m4 6 | /autom4te.cache 7 | /compile 8 | /config.* 9 | /configure 10 | /depcomp 11 | /install-sh 12 | /libdvdcss.la 13 | /libdvdcss.spec 14 | /libdvdcss*.tar.* 15 | /libtool 16 | /ltmain.sh 17 | /missing 18 | /stamp-* 19 | /doc/doxygen.cfg 20 | /doc/doxygen_sqlite3.db 21 | /doc/html 22 | /m4/libtool.m4 23 | /m4/lt*.m4 24 | /src/*.lo 25 | /src/*.o 26 | /src/.deps 27 | /src/.dirstamp 28 | /src/.libs 29 | /src/libdvdcss.pc 30 | /test/*.exe 31 | /test/*.o 32 | /test/.deps 33 | /test/.dirstamp 34 | /test/.libs 35 | /test/csstest 36 | /test/dvd_region 37 | -------------------------------------------------------------------------------- /msvc/workspace.dsw: -------------------------------------------------------------------------------- 1 | Microsoft Developer Studio Workspace File, Format Version 6.00 2 | # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! 3 | 4 | ############################################################################### 5 | 6 | Project: "csstest"=.\csstest.dsp - Package Owner=<4> 7 | 8 | Package=<5> 9 | {{{ 10 | }}} 11 | 12 | Package=<4> 13 | {{{ 14 | Begin Project Dependency 15 | Project_Dep_Name libdvdcss 16 | End Project Dependency 17 | }}} 18 | 19 | ############################################################################### 20 | 21 | Project: "libdvdcss"=.\libdvdcss.dsp - Package Owner=<4> 22 | 23 | Package=<5> 24 | {{{ 25 | }}} 26 | 27 | Package=<4> 28 | {{{ 29 | }}} 30 | 31 | ############################################################################### 32 | 33 | Global: 34 | 35 | Package=<5> 36 | {{{ 37 | }}} 38 | 39 | Package=<3> 40 | {{{ 41 | }}} 42 | 43 | ############################################################################### 44 | 45 | -------------------------------------------------------------------------------- /msvc/config.h: -------------------------------------------------------------------------------- 1 | /* config.h. Generated by hand. */ 2 | 3 | /* #undef DARWIN_DVD_IOCTL */ 4 | /* #undef DVD_STRUCT_IN_DVD_H */ 5 | /* #undef DVD_STRUCT_IN_LINUX_CDROM_H */ 6 | /* #undef DVD_STRUCT_IN_SYS_CDIO_H */ 7 | /* #undef DVD_STRUCT_IN_SYS_DVDIO_H */ 8 | /* #undef HAVE_BSD_DVD_STRUCT */ 9 | #define HAVE_DLFCN_H 1 10 | /* #undef HAVE_DVD_H */ 11 | /* #undef HAVE_INTTYPES_H */ 12 | /* #undef HAVE_LINUX_CDROM_H */ 13 | /* #undef HAVE_LINUX_DVD_STRUCT */ 14 | #define HAVE_MEMORY_H 1 15 | /* #undef HAVE_OPENBSD_DVD_STRUCT */ 16 | #define HAVE_STDLIB_H 1 17 | #define HAVE_STRINGS_H 1 18 | #define HAVE_STRING_H 1 19 | /* #undef HAVE_SYS_CDIO_H */ 20 | /* #undef HAVE_SYS_DVDIO_H */ 21 | #define HAVE_SYS_IOCTL_H 1 22 | /* #undef HAVE_SYS_PARAM_H */ 23 | #define HAVE_SYS_STAT_H 1 24 | #define HAVE_SYS_TYPES_H 1 25 | /* #undef HAVE_UNISTD_H */ 26 | #define HAVE_WINDOWS_H 1 27 | #define HAVE_WINIOCTL_H 1 28 | /* #undef HAVE__SYS_DEV_SCSI_SCSI_IOCTL_H */ 29 | #define PACKAGE "libdvdcss" 30 | #define PACKAGE_BUGREPORT "" 31 | #define PACKAGE_NAME "libdvdcss" 32 | #define PACKAGE_STRING "libdvdcss 1.3.0" 33 | #define PACKAGE_TARNAME "libdvdcss" 34 | #define PACKAGE_VERSION "1.3.0" 35 | /* #undef SOLARIS_USCSI */ 36 | #define STDC_HEADERS 1 37 | #define VERSION "1.3.0" 38 | #define _WIN32_IE 0x0501 39 | /* #undef const */ 40 | /* #undef inline */ 41 | /* #undef size_t */ 42 | #define HAVE_BROKEN_MKDIR 1 43 | #define _CRT_SECURE_NO_WARNINGS 1 44 | #define LIBDVDCSS_EXPORTS 1 45 | -------------------------------------------------------------------------------- /src/dvdcss/version.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of libdvdcss 3 | * Copyright (C) 2015 VideoLAN 4 | * 5 | * This file is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This file is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library. If not, see 17 | * . 18 | */ 19 | 20 | #ifndef DVDCSS_VERSION_H_ 21 | #define DVDCSS_VERSION_H_ 22 | 23 | #define DVDCSS_VERSION_CODE(major, minor, micro) \ 24 | (((major) * 10000) + \ 25 | ((minor) * 100) + \ 26 | ((micro) * 1)) 27 | 28 | #define DVDCSS_VERSION_MAJOR @DVDCSS_VERSION_MAJOR@ 29 | #define DVDCSS_VERSION_MINOR @DVDCSS_VERSION_MINOR@ 30 | #define DVDCSS_VERSION_MICRO @DVDCSS_VERSION_MICRO@ 31 | 32 | #define DVDCSS_VERSION_STRING "@DVDCSS_VERSION_MAJOR@.@DVDCSS_VERSION_MINOR@.@DVDCSS_VERSION_MICRO@" 33 | 34 | #define DVDCSS_VERSION \ 35 | DVDCSS_VERSION_CODE(DVDCSS_VERSION_MAJOR, DVDCSS_VERSION_MINOR, DVDCSS_VERSION_MICRO) 36 | 37 | #endif /* DVDCSS_VERSION_H_ */ 38 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | INSTALL file for libdvdcss, a DVD access library 2 | 3 | 4 | Configuring libdvdcss 5 | ===================== 6 | 7 | A typical way to configure libdvdcss is: 8 | 9 | ./configure --prefix=/usr 10 | 11 | See `./configure --help' for more information. 12 | 13 | 14 | If you got libdvdcss from its version control system, please bootstrap first: 15 | 16 | autoreconf -i 17 | 18 | 19 | Building libdvdcss 20 | ================== 21 | 22 | Once configured, run `make' to build libdvdcss. 23 | 24 | If you have player keys, you need to put them in the file csskeys.h, before 25 | configuring libdvdcss to enable the "key" method (the one from libcss). 26 | 27 | 28 | Installing libdvdcss 29 | ==================== 30 | 31 | You can install libdvdcss by typing: 32 | 33 | make install 34 | 35 | 36 | Building libdvdcss for Windows 37 | ============================== 38 | 39 | There are two alternative ways to build libdvdcss for Windows. 40 | 41 | - on a host with the mingw-w64 cross-compilers: 42 | 43 | Tell configure about the compiler to use. If you run, for example, Debian, 44 | Ubuntu, or Cygwin under Windows with the necessary mingw64 packages 45 | installed, it would be: 46 | 47 | for a 32-bit target platform: 48 | ./configure --host=i686-w64-mingw32 49 | make 50 | 51 | or for a 64-bit target platform: 52 | ./configure --host=x86_64-w64-mingw32 53 | make 54 | 55 | - natively on Windows with MSYS + MinGW (www.mingw.org): 56 | 57 | (MSYS is a minimal build environment to compile Unixish projects under 58 | Windows. It provides all the common Unix tools like sh, GNU Make...) 59 | 60 | You will need to download and install the latest MSYS and MinGW. 61 | 62 | To build libdvdcss you just have to run the following commands: 63 | 64 | ./configure 65 | make 66 | 67 | More about MSYS on our wiki: http://wiki.videolan.org/Win32CompileMSYS 68 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - build 3 | 4 | variables: 5 | GIT_SUBMODULE_STRATEGY: normal 6 | 7 | .build-common: 8 | stage: build 9 | except: 10 | - schedules 11 | 12 | .build-docker: 13 | extends: .build-common 14 | tags: 15 | - docker 16 | - amd64 17 | 18 | build-debian: 19 | extends: .build-docker 20 | image: registry.videolan.org/vlc-debian-unstable:20210315112333 21 | script: 22 | - autoreconf -fisv 23 | - mkdir build 24 | - cd build 25 | - ../configure 26 | - make -j $(getconf _NPROCESSORS_ONLN) 27 | 28 | build-macos: 29 | extends: .build-common 30 | tags: 31 | - catalina 32 | - amd64 33 | script: 34 | - autoreconf -fisv 35 | - mkdir build 36 | - cd build 37 | - ../configure 38 | - make -j $(getconf _NPROCESSORS_ONLN) 39 | 40 | build-win64: 41 | extends: .build-docker 42 | image: registry.videolan.org/vlc-debian-win64:20201106143728 43 | script: 44 | - autoreconf -fisv 45 | - mkdir build 46 | - cd build 47 | - ../configure --host=x86_64-w64-mingw32 48 | - make -j $(getconf _NPROCESSORS_ONLN) 49 | 50 | build-win32: 51 | extends: .build-docker 52 | image: registry.videolan.org/vlc-debian-win32:20201106141924 53 | script: 54 | - autoreconf -fisv 55 | - mkdir build 56 | - cd build 57 | - ../configure --host=i686-w64-mingw32 58 | - make -j $(getconf _NPROCESSORS_ONLN) 59 | 60 | pages: 61 | extends: .build-docker 62 | image: 63 | name: registry.videolan.org/vlc-debian-unstable:20210315112333 64 | script: 65 | - autoreconf -fisv 66 | - ./configure 67 | - make apidoc 68 | - mv doc/html public 69 | artifacts: 70 | paths: 71 | - public 72 | only: 73 | - schedules 74 | except: 75 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # The format of this file was inspired by the Linux kernel CREDITS file. 2 | # 3 | # Authors and contributors are listed alphabetically. 4 | # 5 | # The fields are: name (N), email (E), web address (W), 6 | # PGP key ID and fingerprint (P), description (D) 7 | 8 | N: Billy Biggs 9 | E: vektor@dumbterm.net 10 | D: libdvdcss enhancements 11 | 12 | N: Diego Biurrun 13 | E: diego@biurrun.de 14 | D: misc build and portability fixes, cleanup 15 | 16 | N: Stéphane Borel 17 | E: stef@via.ecp.fr 18 | D: original CSS decryption code from VLC 19 | 20 | N: Sven Heithecker 21 | E: sven.heithecker@web.de 22 | D: cache bug fix for discs with identical content but different keys 23 | 24 | N: Håkan Hjort 25 | E: d95hjort@dtek.chalmers.se 26 | D: Solaris port of the DVD ioctls 27 | D: libdvdcss enhancements 28 | 29 | N: Samuel Hocevar 30 | E: sam@zoy.org 31 | D: original CSS decryption code from VLC 32 | 33 | N: Eugenio Jarosiewicz 34 | E: ej0@cise.ufl.edu 35 | D: Mac OS X DVD ioctls 36 | 37 | N: Jon Lech Johansen 38 | E: jon-vl@nanocrew.net 39 | D: Win32 port 40 | D: Fixes to the Darwin port 41 | 42 | N: KO Myung-Hun 43 | E: komh@chollian.net 44 | D: OS/2 port 45 | 46 | N: Jean-Baptiste Kempf 47 | E: jb@videolan.org 48 | D: maintainer 49 | 50 | N: Markus Kuespert 51 | E: ltlBeBoy@beosmail.com 52 | D: BeOS port of the DVD ioctls 53 | 54 | N: Pascal Levesque 55 | E: Pascal.Levesque@mindready.com 56 | D: QNX port 57 | 58 | N: Steve Lhomme 59 | E: steve.lhomme@free.fr 60 | D: Windows improvements 61 | 62 | N: Christophe Massiot 63 | E: massiot@via.ecp.fr 64 | D: former maintainer 65 | 66 | N: Diego Elio Pettenò 67 | E: flameeyes@flameeyes.eu 68 | D: build system rewrite 69 | 70 | N: Steven M. Schultz 71 | E: sms@TO.GD-ES.COM 72 | D: BSD/OS port 73 | 74 | N: David Siebörger 75 | E: drs-videolan@rucus.ru.ac.za 76 | D: HP-UX port of the DVD ioctls 77 | 78 | N: Alex Strelnikov 79 | E: lelik@os2.ru 80 | D: OS/2 port 81 | 82 | N: German Tischler 83 | E: tanis@gaspode.franken.de 84 | D: FreeBSD DVD input 85 | 86 | N: Gildas Bazin 87 | E: gbazin@netcourrier.com 88 | D: various fixes to the Windows port 89 | -------------------------------------------------------------------------------- /cmake/CheckFileOffsetBits.cmake: -------------------------------------------------------------------------------- 1 | # - Check if _FILE_OFFSET_BITS macro needed for large files 2 | # CHECK_FILE_OFFSET_BITS () 3 | # 4 | # The following variables may be set before calling this macro to 5 | # modify the way the check is run: 6 | # 7 | # CMAKE_REQUIRED_FLAGS = string of compile command line flags 8 | # CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) 9 | # CMAKE_REQUIRED_INCLUDES = list of include directories 10 | # Copyright (c) 2009, Michihiro NAKAJIMA 11 | # 12 | # Redistribution and use is allowed according to the terms of the BSD license. 13 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 14 | 15 | #INCLUDE(CheckCXXSourceCompiles) 16 | 17 | GET_FILENAME_COMPONENT(_selfdir_CheckFileOffsetBits 18 | "${CMAKE_CURRENT_LIST_FILE}" PATH) 19 | 20 | MACRO (CHECK_FILE_OFFSET_BITS) 21 | IF(NOT DEFINED _FILE_OFFSET_BITS) 22 | MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files") 23 | TRY_COMPILE(__WITHOUT_FILE_OFFSET_BITS_64 24 | ${CMAKE_CURRENT_BINARY_DIR} 25 | ${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c 26 | COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}) 27 | IF(NOT __WITHOUT_FILE_OFFSET_BITS_64) 28 | TRY_COMPILE(__WITH_FILE_OFFSET_BITS_64 29 | ${CMAKE_CURRENT_BINARY_DIR} 30 | ${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c 31 | COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_FILE_OFFSET_BITS=64) 32 | ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64) 33 | 34 | IF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64) 35 | SET(_FILE_OFFSET_BITS 64 CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files") 36 | MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files - needed") 37 | ELSE(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64) 38 | SET(_FILE_OFFSET_BITS "" CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files") 39 | MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files - not needed") 40 | ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64) 41 | ENDIF(NOT DEFINED _FILE_OFFSET_BITS) 42 | 43 | ENDMACRO (CHECK_FILE_OFFSET_BITS) 44 | 45 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src/dvdcss 3 | 4 | EXTRA_DIST = msvc libdvdcss.spec INSTALL 5 | 6 | dist_doc_DATA = AUTHORS COPYING NEWS README.md ChangeLog 7 | 8 | MAINTAINERCLEANFILES = ChangeLog 9 | 10 | ChangeLog: $(wildcard $(srcdir)/.git/logs/HEAD) 11 | if GIT 12 | -cd $(srcdir) && git log > $(abs_builddir)/$(@)-tmp 13 | test -s $(@)-tmp && mv $(@)-tmp $(@) 14 | -rm -f $(@)-tmp 15 | endif 16 | test -e $(@) || touch $(@) 17 | 18 | lib_LTLIBRARIES = libdvdcss.la 19 | EXTRA_PROGRAMS = test/csstest test/dvd_region 20 | 21 | libdvdcss_la_SOURCES = \ 22 | src/libdvdcss.c \ 23 | src/libdvdcss.h \ 24 | src/device.c \ 25 | src/device.h \ 26 | src/css.c \ 27 | src/css.h \ 28 | src/csstables.h \ 29 | src/ioctl.c \ 30 | src/ioctl.h \ 31 | src/error.c \ 32 | src/common.h 33 | 34 | libdvdcss_la_LDFLAGS = -version-info $(DVDCSS_LTVERSION) $(DVDCSS_LDFLAGS) 35 | libdvdcss_la_LIBADD = 36 | 37 | if !SYS_MSVC 38 | libdvdcss_la_LDFLAGS += -no-undefined 39 | endif 40 | 41 | test_csstest_SOURCES = test/csstest.c 42 | test_csstest_LDADD = libdvdcss.la 43 | test_csstest_CFLAGS = -I $(top_srcdir)/src 44 | 45 | test_dvd_region_SOURCES = test/dvd_region.c 46 | test_dvd_region_LDADD = libdvdcss.la 47 | test_dvd_region_CFLAGS = -I $(top_srcdir)/src 48 | 49 | pkgincludedir = $(includedir)/dvdcss 50 | pkginclude_HEADERS = \ 51 | src/dvdcss/dvdcss.h \ 52 | src/dvdcss/version.h 53 | 54 | pkgconfigdir = $(libdir)/pkgconfig 55 | pkgconfig_DATA = src/libdvdcss.pc 56 | 57 | if APIDOC 58 | all-local: apidoc 59 | install-data-local: install-apidoc 60 | uninstall-hook: uninstall-apidoc 61 | endif 62 | 63 | apidoc: stamp-doxygen 64 | 65 | stamp-doxygen: doc/doxygen.cfg src/libdvdcss.c src/dvdcss/dvdcss.h 66 | doxygen $< 67 | touch $@ 68 | 69 | tools: test/csstest$(EXEEXT) test/dvd_region$(EXEEXT) 70 | 71 | clean-local: 72 | -rm -Rf stamp-doxygen doc/doxygen_sqlite3.db libdvdcss.spec doc/html 73 | 74 | install-apidoc: 75 | $(MKDIR_P) $(DESTDIR)$(htmldir) 76 | for file in doc/html/*; do \ 77 | $(INSTALL_DATA) $$file "$(DESTDIR)$(htmldir)" || exit 1; \ 78 | done; 79 | 80 | uninstall-apidoc: 81 | -rm -Rf $(DESTDIR)$(htmldir)/*.png $(DESTDIR)$(htmldir)/*.html $(DESTDIR)$(htmldir)/*.css $(DESTDIR)$(htmldir)/*.js 82 | 83 | .PHONY: apidoc tools 84 | -------------------------------------------------------------------------------- /src/device.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * device.h: DVD device access 3 | ***************************************************************************** 4 | * Copyright (C) 1998-2002 VideoLAN 5 | * 6 | * Authors: Stéphane Borel 7 | * Sam Hocevar 8 | * Håkan Hjort 9 | * 10 | * libdvdcss is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * libdvdcss is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License along 21 | * with libdvdcss; if not, write to the Free Software Foundation, Inc., 22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 23 | *****************************************************************************/ 24 | 25 | #ifndef DVDCSS_DEVICE_H 26 | #define DVDCSS_DEVICE_H 27 | 28 | #include "config.h" 29 | 30 | /***************************************************************************** 31 | * iovec structure: vectored data entry 32 | *****************************************************************************/ 33 | #ifndef HAVE_SYS_UIO_H 34 | # include /* read() */ 35 | struct iovec 36 | { 37 | void *iov_base; /* Pointer to data. */ 38 | size_t iov_len; /* Length of data. */ 39 | }; 40 | #else 41 | # include 42 | # include /* struct iovec */ 43 | #endif 44 | 45 | #include "dvdcss/dvdcss.h" 46 | 47 | 48 | /***************************************************************************** 49 | * Device reading prototypes 50 | *****************************************************************************/ 51 | int dvdcss_use_ioctls ( dvdcss_t ); 52 | void dvdcss_check_device ( dvdcss_t ); 53 | int dvdcss_open_device ( dvdcss_t ); 54 | int dvdcss_close_device ( dvdcss_t ); 55 | 56 | #endif /* DVDCSS_DEVICE_H */ 57 | -------------------------------------------------------------------------------- /src/error.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * error.c: error management functions 3 | ***************************************************************************** 4 | * Copyright (C) 1998-2002 VideoLAN 5 | * 6 | * Author: Sam Hocevar 7 | * 8 | * libdvdcss is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * libdvdcss is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License along 19 | * with libdvdcss; if not, write to the Free Software Foundation, Inc., 20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | *****************************************************************************/ 22 | 23 | #include 24 | #include 25 | 26 | #include "libdvdcss.h" 27 | 28 | static void print_message( const char *prefix, const char *psz_string, 29 | va_list args ) 30 | { 31 | fprintf( stderr, "libdvdcss %s: ", prefix ); 32 | vfprintf( stderr, psz_string, args ); 33 | fprintf( stderr, "\n" ); 34 | } 35 | 36 | /***************************************************************************** 37 | * Error messages 38 | *****************************************************************************/ 39 | void print_error( dvdcss_t dvdcss, const char *psz_string, ... ) 40 | { 41 | if( dvdcss->b_errors ) 42 | { 43 | va_list args; 44 | 45 | va_start( args, psz_string ); 46 | print_message("error", psz_string, args); 47 | va_end( args ); 48 | } 49 | 50 | dvdcss->psz_error = psz_string; 51 | } 52 | 53 | /***************************************************************************** 54 | * Debug messages 55 | *****************************************************************************/ 56 | void print_debug( const dvdcss_t dvdcss, const char *psz_string, ... ) 57 | { 58 | if( dvdcss->b_debug ) 59 | { 60 | va_list args; 61 | 62 | va_start( args, psz_string ); 63 | print_message("debug", psz_string, args ); 64 | va_end( args ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/css.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * css.h: Structures for DVD authentication and unscrambling 3 | ***************************************************************************** 4 | * Copyright (C) 1999-2001 VideoLAN 5 | * 6 | * Author: Stéphane Borel 7 | * 8 | * based on: 9 | * - css-auth by Derek Fawcus 10 | * - DVD CSS ioctls example program by Andrew T. Veliath 11 | * - DeCSSPlus by Ethan Hawke 12 | * - The Divide and conquer attack by Frank A. Stevenson 13 | * 14 | * libdvdcss is free software; you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation; either version 2 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * libdvdcss is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License along 25 | * with libdvdcss; if not, write to the Free Software Foundation, Inc., 26 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 27 | *****************************************************************************/ 28 | 29 | #ifndef DVDCSS_CSS_H 30 | #define DVDCSS_CSS_H 31 | 32 | #include 33 | 34 | #include "dvdcss/dvdcss.h" 35 | 36 | #define CACHE_FILENAME_LENGTH_STRING "10" 37 | 38 | #define DVD_KEY_SIZE 5 39 | 40 | typedef uint8_t dvd_key[DVD_KEY_SIZE]; 41 | 42 | typedef struct dvd_title 43 | { 44 | int i_startlb; 45 | dvd_key p_key; 46 | struct dvd_title *p_next; 47 | } dvd_title; 48 | 49 | typedef struct css 50 | { 51 | int i_agid; /* Current Authentication Grant ID. */ 52 | dvd_key p_bus_key; /* Current session key. */ 53 | dvd_key p_disc_key; /* This DVD disc's key. */ 54 | dvd_key p_title_key; /* Current title key. */ 55 | } css; 56 | 57 | /***************************************************************************** 58 | * Prototypes in css.c 59 | *****************************************************************************/ 60 | int dvdcss_test ( dvdcss_t ); 61 | int dvdcss_title ( dvdcss_t, int ); 62 | int dvdcss_disckey ( dvdcss_t ); 63 | int dvdcss_unscramble ( uint8_t *, uint8_t * ); 64 | 65 | #endif /* DVDCSS_CSS_H */ 66 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * common.h: common definitions 3 | * Collection of useful common types and macros definitions 4 | ***************************************************************************** 5 | * Copyright (C) 1998, 1999, 2000 VideoLAN 6 | * 7 | * Authors: Sam Hocevar 8 | * Vincent Seguin 9 | * Gildas Bazin 10 | * 11 | * libdvdcss is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * libdvdcss is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with libdvdcss; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | *****************************************************************************/ 25 | 26 | #ifndef DVDCSS_COMMON_H 27 | #define DVDCSS_COMMON_H 28 | 29 | #if defined( _WIN32 ) 30 | # include /* _lseeki64 */ 31 | 32 | /* several type definitions */ 33 | # if defined( __MINGW32__ ) 34 | # undef lseek 35 | # define lseek _lseeki64 36 | # if !defined( _OFF_T_ ) 37 | typedef long long _off_t; 38 | typedef _off_t off_t; 39 | # define _OFF_T_ 40 | # else 41 | # define off_t long long 42 | # endif 43 | # endif /* defined( __MINGW32__ ) */ 44 | 45 | # if defined( _MSC_VER ) 46 | # undef lseek 47 | # define lseek _lseeki64 48 | # if !defined( _OFF_T_DEFINED ) 49 | typedef __int64 off_t; 50 | # define _OFF_T_DEFINED 51 | # else 52 | # define off_t __int64 53 | # endif 54 | # define ssize_t SSIZE_T 55 | # define snprintf _snprintf 56 | # define strdup _strdup 57 | # define open _open 58 | # define close _close 59 | # define read _read 60 | # define write _write 61 | # endif /* defined( _MSC_VER ) */ 62 | 63 | #endif /* defined( _WIN32 ) */ 64 | 65 | #ifdef __ANDROID__ 66 | # undef lseek 67 | # define lseek lseek64 68 | # undef off_t 69 | # define off_t off64_t 70 | #endif /* __ANDROID__ */ 71 | 72 | #endif /* DVDCSS_COMMON_H */ 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Goals and feature 2 | 3 | **Libdvdcss** is a portable abstraction **lib**rary for **DVD** decryption. 4 | 5 | It is part of the **VideoLAN** project, which among other things produces **VLC**, a full video client/server streaming solution. 6 | 7 | **VLC** can also be used as a standalone program to **play video streams** from a hard disk or a DVD. 8 | 9 | 10 | **Libdvdcss** currently supported platforms are **GNU/Linux**, **FreeBSD**, **NetBSD**, **OpenBSD**, **Haiku**, **Mac OS X**, **Solaris**, **QNX**, **OS/2**, and **Windows NT 4.0 SP4** (with IE 5.0) or later. 11 | 12 | ## Building and installing instructions for Libdvdcss 13 | 14 | See the [INSTALL file](https://code.videolan.org/videolan/libdvdcss/-/blob/master/INSTALL) for full instructions. 15 | 16 | 17 | ## Running libdvdcss 18 | 19 | 20 | The behavior of the library can be changed by setting two environment variables : 21 | 22 | `DVDCSS_METHOD={title|disc|key}`: method for **key decryption** : 23 | 24 | - **title** : By default the decrypted title key is guessed from the encrypted 25 | sectors of the stream. Thus it should work with a file as well as 26 | the DVD device. But decrypting a title key may take too much time 27 | or even fail. With the **title method**, the key is only checked at 28 | the **beginning of each title**, so it will not work if the key 29 | changes in the middle of a title. 30 | 31 | - **disc** : The disc key is **cracked first**. Afterwards all title keys can be 32 | decrypted **instantly**, which allows checking them often. 33 | 34 | - **key** : The same as the "disc" method if you do not have a file with player 35 | keys at compile time. If you do, disc key decryption will be faster. 36 | This is the **default method** also employed by libcss. 37 | 38 | 39 | `DVDCSS_VERBOSE={0|1|2}`: libdvdcss **verbosity** 40 | 41 | - **0**: no error messages, no debug messages (this is the default) 42 | - **1**: only error messages 43 | - **2**: error and debug messages 44 | 45 | 46 | ## Troubleshooting 47 | 48 | 49 | A **mailing-list** has been set up for support and discussion about 50 | libdvdcss. Its address is: 51 | 52 | 53 | 54 | To subscribe or unsubscribe, go [here](http://mailman.videolan.org/). 55 | 56 | 57 | When reporting **bugs**, try to be as **precise** as possible (which OS, which 58 | distribution, what plugins you were trying, and so on). 59 | 60 | ## CoC 61 | 62 | The [VideoLAN Code of Conduct](https://wiki.videolan.org/CoC) applies to this project. 63 | 64 | ## Licence 65 | 66 | **Libdvdcss** is released under the **General Public License**, ensuring it will stay free, and used only for free software products. 67 | 68 | ## Resources 69 | 70 | 71 | The [VideoLAN web site](http://www.videolan.org/) is a good start for 72 | information about MPEG and DVD playback. 73 | 74 | Have a look at the [support section](https://www.videolan.org/support/) to look for answers. 75 | 76 | You can also have a look to [the documentation](https://videolan.videolan.me/libdvdcss/). 77 | -------------------------------------------------------------------------------- /msvc/uwpapi.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace Platform; 8 | using namespace Windows::ApplicationModel; 9 | using namespace Windows::System::UserProfile; 10 | using namespace Windows::Storage; 11 | using namespace Windows::Storage::Streams; 12 | using namespace Windows::Security::Cryptography; 13 | using namespace Windows::Security::Cryptography::Certificates; 14 | using namespace Windows::Foundation; 15 | 16 | std::wstring Utf8ToWide(const std::string &text) 17 | { 18 | if (text.empty()) 19 | return L""; 20 | 21 | int bufSize = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, text.c_str(), -1, NULL, 0); 22 | if (bufSize == 0) 23 | return L""; 24 | wchar_t *converted = new wchar_t[bufSize]; 25 | if (MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, text.c_str(), -1, converted, bufSize) != bufSize) 26 | { 27 | delete[] converted; 28 | return L""; 29 | } 30 | 31 | std::wstring Wret(converted); 32 | delete[] converted; 33 | return Wret; 34 | } 35 | 36 | std::string WideToUtf8(const std::wstring &text) 37 | { 38 | if (text.empty()) 39 | return ""; 40 | 41 | int bufSize = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, text.c_str(), -1, NULL, 0, NULL, NULL); 42 | if (bufSize == 0) 43 | return ""; 44 | char * converted = new char[bufSize]; 45 | if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, text.c_str(), -1, converted, bufSize, NULL, NULL) != bufSize) 46 | { 47 | delete[] converted; 48 | return ""; 49 | } 50 | 51 | std::string ret(converted); 52 | delete[] converted; 53 | 54 | return ret; 55 | } 56 | 57 | extern "C" { 58 | 59 | size_t uwp_Utf8ToW(const char* src, wchar_t* buffer, int maxlen) 60 | { 61 | std::wstring converted = Utf8ToWide(std::string(src)); 62 | int len = min(converted.length(), maxlen - 1); 63 | wcsncpy(buffer, converted.c_str(), len); 64 | buffer[len] = '\0'; 65 | 66 | return len; 67 | } 68 | 69 | size_t uwp_cachepath(char *buffer, size_t cch) 70 | { 71 | try 72 | { 73 | Platform::String^ path = Windows::Storage::ApplicationData::Current->LocalFolder->Path; 74 | path = Platform::String::Concat(path, "\\dvdcss"); 75 | 76 | std::string utf8path = WideToUtf8(std::wstring(path->Data())); 77 | 78 | strncpy(buffer, utf8path.c_str(), min(cch, path->Length())); 79 | return min(cch, path->Length()); 80 | } 81 | catch (Platform::Exception^) 82 | { 83 | return 0; 84 | } 85 | } 86 | 87 | char* uwp_getenv(const char* n) 88 | { 89 | static std::map sEnvironment; 90 | 91 | if (n == nullptr) 92 | return nullptr; 93 | 94 | std::string name(n); 95 | 96 | // check key 97 | if (!name.empty()) 98 | { 99 | uint32_t valLen = GetEnvironmentVariableA(name.c_str(), nullptr, 0); 100 | if (!valLen) 101 | return nullptr; 102 | 103 | std::string value(valLen, 0); 104 | GetEnvironmentVariableA(name.c_str(), const_cast(value.c_str()), valLen); 105 | 106 | sEnvironment[name] = value; 107 | return const_cast(sEnvironment[name].c_str()); 108 | } 109 | return nullptr; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/libdvdcss.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * libdvdcss.h: private DVD reading library data 3 | ***************************************************************************** 4 | * Copyright (C) 1998-2001 VideoLAN 5 | * 6 | * Authors: Stéphane Borel 7 | * Sam Hocevar 8 | * 9 | * libdvdcss is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * libdvdcss is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along 20 | * with libdvdcss; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 | *****************************************************************************/ 23 | 24 | #ifndef DVDCSS_LIBDVDCSS_H 25 | #define DVDCSS_LIBDVDCSS_H 26 | 27 | #include 28 | 29 | #include "dvdcss/dvdcss.h" 30 | #include "css.h" 31 | #include "device.h" 32 | 33 | /***************************************************************************** 34 | * libdvdcss method: used like init flags 35 | *****************************************************************************/ 36 | enum dvdcss_method { 37 | DVDCSS_METHOD_KEY, 38 | DVDCSS_METHOD_DISC, 39 | DVDCSS_METHOD_TITLE, 40 | }; 41 | /***************************************************************************** 42 | * The libdvdcss structure 43 | *****************************************************************************/ 44 | struct dvdcss_s 45 | { 46 | /* File descriptor */ 47 | char * psz_device; 48 | int i_fd; 49 | int i_pos; 50 | 51 | /* File handling */ 52 | int ( * pf_seek ) ( dvdcss_t, int ); 53 | int ( * pf_read ) ( dvdcss_t, void *, int ); 54 | int ( * pf_readv ) ( dvdcss_t, const struct iovec *, int ); 55 | 56 | /* Decryption stuff */ 57 | enum dvdcss_method i_method; 58 | struct css css; 59 | int b_ioctls; 60 | int b_scrambled; 61 | struct dvd_title *p_titles; 62 | 63 | /* Key cache directory and pointer to the filename */ 64 | char psz_cachefile[PATH_MAX]; 65 | char * psz_block; 66 | 67 | /* Error management */ 68 | const char *psz_error; 69 | int b_errors; 70 | int b_debug; 71 | 72 | #ifdef _WIN32 73 | int b_file; 74 | char * p_readv_buffer; 75 | int i_readv_buf_size; 76 | #endif /* _WIN32 */ 77 | 78 | void *p_stream; 79 | dvdcss_stream_cb *p_stream_cb; 80 | }; 81 | 82 | /***************************************************************************** 83 | * Functions used across the library 84 | *****************************************************************************/ 85 | void print_error ( dvdcss_t, const char *, ... ); 86 | void print_debug ( const dvdcss_t, const char *, ... ); 87 | 88 | #endif /* DVDCSS_LIBDVDCSS_H */ 89 | -------------------------------------------------------------------------------- /src/dvdcss/dvdcss.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file dvdcss.h 3 | * \author Stéphane Borel 4 | * \author Sam Hocevar 5 | * 6 | * \brief The \e libdvdcss public header. 7 | * 8 | * Public types and functions that describe the API of the \e libdvdcss library. 9 | */ 10 | 11 | /* 12 | * Copyright (C) 1998-2008 VideoLAN 13 | * 14 | * libdvdcss is free software; you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation; either version 2 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * libdvdcss is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License along 25 | * with libdvdcss; if not, write to the Free Software Foundation, Inc., 26 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 27 | */ 28 | 29 | #ifndef DVDCSS_DVDCSS_H 30 | #ifndef _DOXYGEN_SKIP_ME 31 | #define DVDCSS_DVDCSS_H 1 32 | #endif 33 | 34 | #include 35 | 36 | #include "version.h" 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | /** Library instance handle, to be used for each library call. */ 43 | typedef struct dvdcss_s* dvdcss_t; 44 | 45 | /** Set of callbacks to access DVDs in custom ways. */ 46 | typedef struct dvdcss_stream_cb 47 | { 48 | /** custom seek callback */ 49 | int ( *pf_seek ) ( void *p_stream, uint64_t i_pos); 50 | /** custom read callback */ 51 | int ( *pf_read ) ( void *p_stream, void *buffer, int i_read); 52 | /** custom vectored read callback */ 53 | int ( *pf_readv ) ( void *p_stream, const void *p_iovec, int i_blocks); 54 | } dvdcss_stream_cb; 55 | 56 | 57 | /** The block size of a DVD. */ 58 | #define DVDCSS_BLOCK_SIZE 2048 59 | 60 | /** The default flag to be used by \e libdvdcss functions. */ 61 | #define DVDCSS_NOFLAGS 0 62 | 63 | /** Flag to ask dvdcss_read() to decrypt the data it reads. */ 64 | #define DVDCSS_READ_DECRYPT (1 << 0) 65 | 66 | /** Flag to tell dvdcss_seek() it is seeking in MPEG data. */ 67 | #define DVDCSS_SEEK_MPEG (1 << 0) 68 | 69 | /** Flag to ask dvdcss_seek() to check the current title key. */ 70 | #define DVDCSS_SEEK_KEY (1 << 1) 71 | 72 | 73 | /** Macro for setting symbol storage-class or visibility. 74 | * Define LIBDVDCSS_IMPORTS before importing this header to get the 75 | * correct DLL storage-class when using \e libdvdcss from MSVC. */ 76 | #if defined(LIBDVDCSS_EXPORTS) 77 | #define LIBDVDCSS_EXPORT __declspec(dllexport) extern 78 | #elif defined(LIBDVDCSS_IMPORTS) 79 | #define LIBDVDCSS_EXPORT __declspec(dllimport) extern 80 | #elif defined(SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT) 81 | #define LIBDVDCSS_EXPORT __attribute__((visibility("default"))) extern 82 | #else 83 | #define LIBDVDCSS_EXPORT extern 84 | #endif 85 | 86 | 87 | /* 88 | * Exported prototypes. 89 | */ 90 | LIBDVDCSS_EXPORT dvdcss_t dvdcss_open ( const char *psz_target ); 91 | LIBDVDCSS_EXPORT dvdcss_t dvdcss_open_stream( void *p_stream, 92 | dvdcss_stream_cb *p_stream_cb ); 93 | LIBDVDCSS_EXPORT int dvdcss_close ( dvdcss_t ); 94 | LIBDVDCSS_EXPORT int dvdcss_seek ( dvdcss_t, 95 | int i_blocks, 96 | int i_flags ); 97 | LIBDVDCSS_EXPORT int dvdcss_read ( dvdcss_t, 98 | void *p_buffer, 99 | int i_blocks, 100 | int i_flags ); 101 | LIBDVDCSS_EXPORT int dvdcss_readv ( dvdcss_t, 102 | void *p_iovec, 103 | int i_blocks, 104 | int i_flags ); 105 | LIBDVDCSS_EXPORT const char *dvdcss_error ( const dvdcss_t ); 106 | 107 | LIBDVDCSS_EXPORT int dvdcss_is_scrambled ( dvdcss_t ); 108 | 109 | #ifdef __cplusplus 110 | } 111 | #endif 112 | 113 | #endif /* DVDCSS_DVDCSS_H */ 114 | -------------------------------------------------------------------------------- /test/csstest.c: -------------------------------------------------------------------------------- 1 | /* csstest.c - test program for libdvdcss 2 | * 3 | * Sam Hocevar - June 2001 4 | * Updated on Nov 13th 2001 for libdvdcss version 1.0.0 5 | * Additional error checks on Aug 9th 2002 6 | * Aligned data reads on Jan 28th 2003 7 | * 8 | * This piece of code is public domain */ 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #define DVDCSS_DSI_PES 0x400 16 | 17 | static int isscrambled( unsigned char * ); 18 | static void dumpsector ( unsigned char * ); 19 | 20 | int main( int i_argc, char *ppsz_argv[] ) 21 | { 22 | dvdcss_t dvdcss; 23 | unsigned char p_data[ DVDCSS_BLOCK_SIZE * 2 ]; 24 | unsigned char *p_buffer; 25 | unsigned int i_sector; 26 | int i_ret; 27 | 28 | /* Check for 2 arguments */ 29 | if( i_argc != 3 ) 30 | { 31 | printf( "usage: %s \n", ppsz_argv[0] ); 32 | printf( "examples:\n" ); 33 | printf( " %s /dev/hdc 1024\n", ppsz_argv[0] ); 34 | printf( " %s D: 1024\n", ppsz_argv[0] ); 35 | printf( " %s scrambledfile.vob 1024\n", ppsz_argv[0] ); 36 | return -1; 37 | } 38 | 39 | /* Save the requested sector */ 40 | i_sector = atoi( ppsz_argv[2] ); 41 | 42 | /* Initialize libdvdcss */ 43 | dvdcss = dvdcss_open( ppsz_argv[1] ); 44 | if( dvdcss == NULL ) 45 | { 46 | printf( "argh ! couldn't open DVD (%s)\n", ppsz_argv[1] ); 47 | return -1; 48 | } 49 | 50 | /* Align our read buffer */ 51 | p_buffer = p_data + DVDCSS_BLOCK_SIZE 52 | - ((long int)p_data & (DVDCSS_BLOCK_SIZE-1)); 53 | 54 | /* Set the file descriptor at sector i_sector and read one sector */ 55 | i_ret = dvdcss_seek( dvdcss, i_sector, DVDCSS_NOFLAGS ); 56 | if( i_ret != (int)i_sector ) 57 | { 58 | printf( "seek failed (%s)\n", dvdcss_error( dvdcss ) ); 59 | dvdcss_close( dvdcss ); 60 | return i_ret; 61 | } 62 | 63 | i_ret = dvdcss_read( dvdcss, p_buffer, 1, DVDCSS_NOFLAGS ); 64 | if( i_ret != 1 ) 65 | { 66 | printf( "read failed (%s)\n", dvdcss_error( dvdcss ) ); 67 | dvdcss_close( dvdcss ); 68 | return i_ret; 69 | } 70 | 71 | /* Print the sector */ 72 | printf( "requested sector:\t" ); 73 | dumpsector( p_buffer ); 74 | 75 | /* Check if sector was encrypted */ 76 | if( isscrambled( p_buffer ) ) 77 | { 78 | /* Set the file descriptor position to the previous location */ 79 | /* ... and get the appropriate key for this sector */ 80 | i_ret = dvdcss_seek( dvdcss, i_sector, DVDCSS_SEEK_KEY ); 81 | if( i_ret != (int)i_sector ) 82 | { 83 | printf( "seek failed (%s)\n", dvdcss_error( dvdcss ) ); 84 | dvdcss_close( dvdcss ); 85 | return i_ret; 86 | } 87 | 88 | /* Read sector again, and decrypt it on the fly */ 89 | i_ret = dvdcss_read( dvdcss, p_buffer, 1, DVDCSS_READ_DECRYPT ); 90 | if( i_ret != 1 ) 91 | { 92 | printf( "read failed (%s)\n", dvdcss_error( dvdcss ) ); 93 | dvdcss_close( dvdcss ); 94 | return i_ret; 95 | } 96 | 97 | /* Print the decrypted sector */ 98 | printf( "unscrambled sector:\t" ); 99 | dumpsector( p_buffer ); 100 | } 101 | else 102 | { 103 | printf( "sector is not scrambled\n" ); 104 | } 105 | 106 | /* Close the device */ 107 | i_ret = dvdcss_close( dvdcss ); 108 | 109 | return i_ret; 110 | } 111 | 112 | /* Check if a sector is scrambled */ 113 | static int isscrambled( unsigned char *p_buffer ) 114 | { 115 | return p_buffer[ 0x14 ] & 0x30; 116 | } 117 | 118 | static void dumpmem( unsigned char *p_buffer, int sz ) 119 | { 120 | for( ; sz ; sz--, p_buffer++ ) 121 | printf( "%.2x", *p_buffer ); 122 | } 123 | 124 | /* Print parts of a 2048 bytes buffer */ 125 | static void dumpsector( unsigned char *p_buffer ) 126 | { 127 | /* print pack header and first PES bytes up to flags */ 128 | dumpmem( &p_buffer[0], 21 ); 129 | printf( "..." ); 130 | /* print DSI up to block number */ 131 | dumpmem( &p_buffer[DVDCSS_DSI_PES], 17 ); 132 | printf( "..." ); 133 | dumpmem( &p_buffer[DVDCSS_BLOCK_SIZE - 8], 8 ); 134 | printf( "\n" ); 135 | } 136 | -------------------------------------------------------------------------------- /msvc/libdvdcss.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="libdvdcss" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Static Library" 0x0104 6 | 7 | CFG=libdvdcss - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "libdvdcss.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "libdvdcss.mak" CFG="libdvdcss - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "libdvdcss - Win32 Release" (based on "Win32 (x86) Static Library") 21 | !MESSAGE "libdvdcss - Win32 Debug" (based on "Win32 (x86) Static Library") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "libdvdcss - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Target_Dir "" 43 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c 44 | # ADD CPP /nologo /W3 /GX /O2 /I "." /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PATH_MAX=2048 /YX /FD /c 45 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 46 | # ADD RSC /l 0x409 /d "NDEBUG" 47 | BSC32=bscmake.exe 48 | # ADD BASE BSC32 /nologo 49 | # ADD BSC32 /nologo 50 | LIB32=link.exe -lib 51 | # ADD BASE LIB32 /nologo 52 | # ADD LIB32 /nologo 53 | 54 | !ELSEIF "$(CFG)" == "libdvdcss - Win32 Debug" 55 | 56 | # PROP BASE Use_MFC 0 57 | # PROP BASE Use_Debug_Libraries 1 58 | # PROP BASE Output_Dir "Debug" 59 | # PROP BASE Intermediate_Dir "Debug" 60 | # PROP BASE Target_Dir "" 61 | # PROP Use_MFC 0 62 | # PROP Use_Debug_Libraries 1 63 | # PROP Output_Dir "Debug" 64 | # PROP Intermediate_Dir "Debug" 65 | # PROP Target_Dir "" 66 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c 67 | # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PATH_MAX=2048 /YX /FD /GZ /c 68 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 69 | # ADD RSC /l 0x409 /d "_DEBUG" 70 | BSC32=bscmake.exe 71 | # ADD BASE BSC32 /nologo 72 | # ADD BSC32 /nologo 73 | LIB32=link.exe -lib 74 | # ADD BASE LIB32 /nologo 75 | # ADD LIB32 /nologo 76 | 77 | !ENDIF 78 | 79 | # Begin Target 80 | 81 | # Name "libdvdcss - Win32 Release" 82 | # Name "libdvdcss - Win32 Debug" 83 | # Begin Group "Source Files" 84 | 85 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 86 | # Begin Source File 87 | 88 | SOURCE=..\src\css.c 89 | # End Source File 90 | # Begin Source File 91 | 92 | SOURCE=..\src\device.c 93 | # End Source File 94 | # Begin Source File 95 | 96 | SOURCE=..\src\error.c 97 | # End Source File 98 | # Begin Source File 99 | 100 | SOURCE=..\src\ioctl.c 101 | # End Source File 102 | # Begin Source File 103 | 104 | SOURCE=..\src\libdvdcss.c 105 | # End Source File 106 | # End Group 107 | # Begin Group "Header Files" 108 | 109 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 110 | # Begin Source File 111 | 112 | SOURCE=..\src\common.h 113 | # End Source File 114 | # Begin Source File 115 | 116 | SOURCE=.\config.h 117 | # End Source File 118 | # Begin Source File 119 | 120 | SOURCE=..\src\css.h 121 | # End Source File 122 | # Begin Source File 123 | 124 | SOURCE=..\src\csstables.h 125 | # End Source File 126 | # Begin Source File 127 | 128 | SOURCE=..\src\device.h 129 | # End Source File 130 | # Begin Source File 131 | 132 | SOURCE=..\src\dvdcss\dvdcss.h 133 | # End Source File 134 | # Begin Source File 135 | 136 | SOURCE=..\src\ioctl.h 137 | # End Source File 138 | # Begin Source File 139 | 140 | SOURCE=..\src\libdvdcss.h 141 | # End Source File 142 | # End Group 143 | # End Target 144 | # End Project 145 | -------------------------------------------------------------------------------- /msvc/csstest.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="csstest" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=csstest - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "csstest.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "csstest.mak" CFG="csstest - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "csstest - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "csstest - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "csstest - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Target_Dir "" 43 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 44 | # ADD CPP /nologo /W3 /GX /O2 /I "." /I "..\src" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 46 | # ADD RSC /l 0x409 /d "NDEBUG" 47 | BSC32=bscmake.exe 48 | # ADD BASE BSC32 /nologo 49 | # ADD BSC32 /nologo 50 | LINK32=link.exe 51 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 52 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | 54 | !ELSEIF "$(CFG)" == "csstest - Win32 Debug" 55 | 56 | # PROP BASE Use_MFC 0 57 | # PROP BASE Use_Debug_Libraries 1 58 | # PROP BASE Output_Dir "csstest___Win32_Debug" 59 | # PROP BASE Intermediate_Dir "csstest___Win32_Debug" 60 | # PROP BASE Target_Dir "" 61 | # PROP Use_MFC 0 62 | # PROP Use_Debug_Libraries 1 63 | # PROP Output_Dir "csstest___Win32_Debug" 64 | # PROP Intermediate_Dir "csstest___Win32_Debug" 65 | # PROP Target_Dir "" 66 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 67 | # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "..\src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 68 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 69 | # ADD RSC /l 0x409 /d "_DEBUG" 70 | BSC32=bscmake.exe 71 | # ADD BASE BSC32 /nologo 72 | # ADD BSC32 /nologo 73 | LINK32=link.exe 74 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 75 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 76 | 77 | !ENDIF 78 | 79 | # Begin Target 80 | 81 | # Name "csstest - Win32 Release" 82 | # Name "csstest - Win32 Debug" 83 | # Begin Group "Source Files" 84 | 85 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 86 | # Begin Source File 87 | 88 | SOURCE=..\test\csstest.c 89 | # End Source File 90 | # End Group 91 | # Begin Group "Header Files" 92 | 93 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 94 | # Begin Source File 95 | 96 | SOURCE=..\src\dvdcss\dvdcss.h 97 | # End Source File 98 | # End Group 99 | # Begin Group "Resource Files" 100 | 101 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 102 | # End Group 103 | # End Target 104 | # End Project 105 | -------------------------------------------------------------------------------- /config.h.cm: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* Have IOKit DVD IOCTL headers */ 4 | #cmakedefine DARWIN_DVD_IOCTL 1 5 | 6 | /* Define if defines DVD_STRUCT. */ 7 | #cmakedefine DVD_STRUCT_IN_LINUX_CDROM_H 1 8 | 9 | /* Define if defines dvd_struct. */ 10 | #cmakedefine DVD_STRUCT_IN_SYS_CDIO_H 1 11 | 12 | /* Define if defines dvd_struct. */ 13 | #cmakedefine DVD_STRUCT_IN_SYS_DVDIO_H 1 14 | 15 | /* Define if you have a broken mkdir */ 16 | #cmakedefine HAVE_BROKEN_MKDIR 1 17 | 18 | /* Define if FreeBSD-like dvd_struct is defined. */ 19 | #cmakedefine HAVE_BSD_DVD_STRUCT 1 20 | 21 | /* Define to 1 if you have the header file. */ 22 | #cmakedefine HAVE_DLFCN_H 1 23 | 24 | /* Define to 1 if you have the header file. */ 25 | #cmakedefine HAVE_DVD_H 1 26 | 27 | /* Define to 1 if you have the header file. */ 28 | #cmakedefine HAVE_ERRNO_H 1 29 | 30 | /* Define to 1 if you have the header file. */ 31 | #cmakedefine HAVE_FCNTL_H 1 32 | 33 | /* Define to 1 if you have the header file. */ 34 | #cmakedefine HAVE_INTTYPES_H 1 35 | 36 | /* Define to 1 if you have the header file. */ 37 | #cmakedefine HAVE_IO_H 1 38 | 39 | /* Define to 1 if you have the header file. */ 40 | #cmakedefine HAVE_LINUX_CDROM_H 1 41 | 42 | /* Define if Linux-like dvd_struct is defined. */ 43 | #cmakedefine HAVE_LINUX_DVD_STRUCT 1 44 | 45 | /* Define to 1 if you have the header file. */ 46 | #cmakedefine HAVE_MEMORY_H 1 47 | 48 | /* Define if OpenBSD-like dvd_struct is defined. */ 49 | #cmakedefine HAVE_OPENBSD_DVD_STRUCT 1 50 | 51 | /* Define to 1 if you have the header file. */ 52 | #cmakedefine HAVE_PWD_H 1 53 | 54 | /* Define to 1 if you have the header file. */ 55 | #cmakedefine HAVE_STDINT_H 1 56 | 57 | /* Define to 1 if you have the header file. */ 58 | #cmakedefine HAVE_STDLIB_H 1 59 | 60 | /* Define to 1 if you have the header file. */ 61 | #cmakedefine HAVE_STRINGS_H 1 62 | 63 | /* Define to 1 if you have the header file. */ 64 | #cmakedefine HAVE_STRING_H 1 65 | 66 | /* Define to 1 if you have the header file. */ 67 | #cmakedefine HAVE_SYS_CDIO_H 1 68 | 69 | /* Define to 1 if you have the header file. */ 70 | #cmakedefine HAVE_SYS_DVDIO_H 1 71 | 72 | /* Define to 1 if you have the header file. */ 73 | #cmakedefine HAVE_SYS_IOCTL_H 1 74 | 75 | /* Define to 1 if you have the header file. */ 76 | #cmakedefine HAVE_SYS_PARAM_H 1 77 | 78 | /* Define to 1 if you have the header file. */ 79 | #cmakedefine HAVE_SYS_SCSI_IMPL_USCSI_H 1 80 | 81 | /* Define to 1 if you have the header file. */ 82 | #cmakedefine HAVE_SYS_SCSI_SCSI_TYPES_H 1 83 | 84 | /* Define to 1 if you have the header file. */ 85 | #cmakedefine HAVE_SYS_STAT_H 1 86 | 87 | /* Define to 1 if you have the header file. */ 88 | #cmakedefine HAVE_SYS_TYPES_H 1 89 | 90 | /* Define to 1 if you have the header file. */ 91 | #cmakedefine HAVE_SYS_UIO_H 1 92 | 93 | /* Define to 1 if you have the header file. */ 94 | #cmakedefine HAVE_UNISTD_H 1 95 | 96 | /* Define to 1 if you have the header file. */ 97 | #cmakedefine HAVE_WINDOWS_H 1 98 | 99 | /* Define to 1 if you have the header file. */ 100 | #cmakedefine HAVE_WINIOCTL_H 1 101 | 102 | /* Define to the sub-directory where libtool stores uninstalled libraries. */ 103 | #cmakedefine LT_OBJDIR "${LT_OBJDIR}" 104 | 105 | /* Define O_BINARY if missing */ 106 | #cmakedefine O_BINARY "${O_BINARY}" 107 | 108 | /* Name of package */ 109 | #cmakedefine PACKAGE "${PACKAGE}" 110 | 111 | /* Define to the address where bug reports for this package should be sent. */ 112 | #cmakedefine PACKAGE_BUGREPORT "${PACKAGE_BUGREPORT}" 113 | 114 | /* Define to the full name of this package. */ 115 | #cmakedefine PACKAGE_NAME "${PACKAGE_NAME}" 116 | 117 | /* Define to the full name and version of this package. */ 118 | #cmakedefine PACKAGE_STRING "${PACKAGE_STRING}" 119 | 120 | /* Define to the one symbol short name of this package. */ 121 | #cmakedefine PACKAGE_TARNAME "${PACKAGE_TARNAME}" 122 | 123 | /* Define to the home page for this package. */ 124 | #cmakedefine PACKAGE_URL "${PACKAGE_URL}" 125 | 126 | /* Define to the version of this package. */ 127 | #cmakedefine PACKAGE_VERSION "${PACKAGE_VERSION}" 128 | 129 | /* Have userspace SCSI headers. */ 130 | #cmakedefine SOLARIS_USCSI 1 131 | 132 | /* Define to 1 if you have the ANSI C header files. */ 133 | #cmakedefine STDC_HEADERS 1 134 | 135 | /* Define this if the compiler supports __attribute__((visibility("default"))) 136 | */ 137 | #cmakedefine SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT 1 138 | 139 | /* Define this if the compiler supports the -fvisibility flag */ 140 | #cmakedefine SUPPORT_FLAG_VISIBILITY 1 141 | 142 | /* Version number of package */ 143 | #cmakedefine VERSION "${VERSION}" 144 | 145 | /* Enable large inode numbers on Mac OS X 10.5. */ 146 | #ifndef _DARWIN_USE_64_BIT_INODE 147 | # define _DARWIN_USE_64_BIT_INODE 1 148 | #endif 149 | 150 | /* Number of bits in a file offset, on hosts where this is settable. */ 151 | #cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS} 152 | 153 | /* Define for large files, on AIX-style hosts. */ 154 | #cmakedefine _LARGE_FILES 1 155 | 156 | /* Define to '0x0501' for IE 5.01 (and shell) APIs. */ 157 | #cmakedefine _WIN32_IE ${_WIN32_IE} 158 | 159 | /* Define to empty if `const' does not conform to ANSI C. */ 160 | /* #undef const */ 161 | 162 | /* Define to `__inline__' or `__inline' if that's what the C compiler 163 | calls it, or to nothing if 'inline' is not supported under any name. */ 164 | #ifndef __cplusplus 165 | #cmakedefine inline 166 | #endif 167 | 168 | /* Define to `unsigned int' if does not define. */ 169 | #cmakedefine size_t ${size_t} 170 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | Changes between 1.4.2 and 1.4.3: 2 | -------------------------------- 3 | 4 | * Fix opening non-ASCII paths in Windows 5 | * Fix potential buffer overflow if PATH_MAX is reached 6 | 7 | 8 | Changes between 1.4.1 and 1.4.2: 9 | -------------------------------- 10 | 11 | * Fix buffer overflow when region mask is 0x0 12 | * Fix invalid free on Open 13 | 14 | 15 | Changes between 1.4.0 and 1.4.1: 16 | -------------------------------- 17 | 18 | * Fix crashes in cache directory creation 19 | * Fix cases where the cache directory was not used 20 | 21 | 22 | Changes between 1.3.99 and 1.4.0: 23 | --------------------------------- 24 | 25 | * Add key caching on Android 26 | * Fix leaks, win32 build breakage, file descriptor initialization 27 | * Expose version.h 28 | 29 | 30 | Changes between 1.3.0 and 1.3.99: 31 | --------------------------------- 32 | 33 | * Drop support for HP-UX. 34 | * Drop support for Windows 9x and Windows NT. 35 | Windows 2000 is now required. 36 | * Replace BeOS support by Haiku support. 37 | * Add dvdcss_open_stream() to public API. This allows installing custom 38 | callback functions for accessing DVD, e.g. over the network. 39 | * dvdcss_error() now returns "const char *" instead of "char *". 40 | * Drop support for MSVC versions before 2010. 41 | * Raw device access now errors out if the device cannot be opened. 42 | * Miscellaneous cleanups to code, documentation, build system. 43 | 44 | 45 | Changes between 1.2.13 and 1.3.0: 46 | --------------------------------- 47 | 48 | * Dropped deprecated, undocumented API: 49 | - the function dvdcss_title() 50 | - the type dvdcss_handle 51 | - the variable dvdcss_interface_2 52 | * Drop support for Windows 98 and Windows NT 4.0. 53 | Windows 98 SE with IE 5.0 and Windows NT 4.0 SP4 with IE 5.0 are required. 54 | * Support for Android 55 | 56 | 57 | Changes between 1.2.12 and 1.2.13: 58 | ---------------------------------- 59 | 60 | * Drop BSD/OS and Windows 95 support. 61 | * Rewrite most of the build system and simplify it. 62 | * System-dependent code cleanup 63 | * Move to Git and rewrite the history to get proper authorship. 64 | * Drop LaTeX documentation. 65 | * Fix build on various systems including MSVC. 66 | 67 | 68 | Changes between 1.2.11 and 1.2.12: 69 | ---------------------------------- 70 | 71 | * Fix regression with RPC-I drive handling. 72 | 73 | 74 | Changes between 1.2.10 and 1.2.11: 75 | ---------------------------------- 76 | 77 | * improvements with RPC-II handling 78 | * more robust key retrieval 79 | * fixes for MinGW compilation 80 | * fixes for OS/2 compilation 81 | * various bug fixes for small issues, memleaks, crashes and build problems 82 | 83 | 84 | Changes between 1.2.9 and 1.2.10: 85 | --------------------------------- 86 | 87 | * DVD drive autodetection 88 | * new dvdcss_is_scrambled() function 89 | * various failure recovery improvements 90 | * accept "X:\", as well as "X:" as device name 91 | * various bug fixes 92 | 93 | Changes between 1.2.8 and 1.2.9: 94 | -------------------------------- 95 | 96 | * more robust key caching 97 | * support for cache directory tags 98 | * improved seeking on Win32 99 | * support for Solaris libsmedia library 100 | 101 | Changes between 1.2.7 and 1.2.8: 102 | -------------------------------- 103 | 104 | * Win32 fix for encrypted DVDs 105 | * workaround for strange discs that report read errors seemingly at random 106 | 107 | Changes between 1.2.6 and 1.2.7: 108 | -------------------------------- 109 | 110 | * key caching activated by default 111 | * fix for collisions between cached keys 112 | * packaging improvements for Debian 113 | * packaging improvements for RPM-based distributions 114 | 115 | Changes between 1.2.5 and 1.2.6: 116 | -------------------------------- 117 | 118 | * compilation fix for most Unixes 119 | 120 | Changes between 1.2.4 and 1.2.5: 121 | -------------------------------- 122 | 123 | * key cache support 124 | * improved robustness in case of read errors 125 | * now builds under Cygwin 126 | * now builds under Microsoft Visual C++ 127 | 128 | Changes between 1.2.3 and 1.2.4: 129 | -------------------------------- 130 | 131 | * Administrator privileges are no longer required under Windows NT/2000/XP. 132 | 133 | Changes between 1.2.2 and 1.2.3: 134 | -------------------------------- 135 | 136 | * many Windows bug fixes 137 | * workaround for drives which prevent key decryption 138 | 139 | Changes between 1.2.1 and 1.2.2: 140 | -------------------------------- 141 | 142 | * fix for the "ioctl_ReadTitleKey failed" bug on RPC2 drives 143 | * better error checking 144 | * improved documentation 145 | * OS/2 port 146 | 147 | Changes between 1.2.0 and 1.2.1: 148 | -------------------------------- 149 | 150 | * fix for discs with a mismatched region 151 | * QNX port 152 | 153 | Changes between 1.1.1 and 1.2.0: 154 | -------------------------------- 155 | 156 | * fix for a crash when an unencrypted sector is found on a scrambled disc 157 | * stability enhancements 158 | 159 | Changes between 1.1.0 and 1.1.1: 160 | -------------------------------- 161 | 162 | * compilation fixes for BeOS, IRIX, OpenBSD 163 | 164 | Changes between 1.0.0 and 1.1.0: 165 | -------------------------------- 166 | 167 | * merged all patches from the Ogle group 168 | * lots of bug fixes 169 | * HP-UX port 170 | * better error recovery 171 | * third descrambling implementation 172 | 173 | Changes between 0.0.3 and 1.0.0: 174 | -------------------------------- 175 | 176 | * stable API 177 | * OpenBSD port 178 | * NetBSD port 179 | * Mac OS X port 180 | 181 | Changes between 0.0.2 and 0.0.3: 182 | -------------------------------- 183 | 184 | * fix to access the whole device under Win32 185 | * BSD/OS port 186 | * Solaris port 187 | 188 | Changes between 0.0.1 and 0.0.2: 189 | -------------------------------- 190 | 191 | * internal key cache mechanism 192 | * stability fixes 193 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") 3 | 4 | project(dvdcss C) 5 | 6 | set(DVDCSS_VERSION_MAJOR 1) 7 | set(DVDCSS_VERSION_MINOR 4) 8 | set(DVDCSS_VERSION_MICRO 1) 9 | 10 | set(LIBDVDCSS_VERSION "${DVDCSS_VERSION_MAJOR}.${DVDCSS_VERSION_MINOR}.${DVDCSS_VERSION_MICRO}") 11 | 12 | include(CheckIncludeFiles) 13 | include(CheckSymbolExists) 14 | include(CheckTypeSize) 15 | include(CheckFileOffsetBits) 16 | 17 | check_include_files("IOKit/storage/IODVDMediaBSDClient.h" DARWIN_DVD_IOCTL) 18 | check_include_files("linux/cdrom.h" DVD_STRUCT_IN_LINUX_CDROM_H) 19 | check_include_files("linux/cdrom.h" HAVE_LINUX_CDROM_H) 20 | check_include_files("sys/cdio.h" DVD_STRUCT_IN_SYS_CDIO_H) 21 | check_include_files("sys/cdio.h" HAVE_SYS_CDIO_H) 22 | check_include_files("sys/dvdio.h" DVD_STRUCT_IN_SYS_DVDIO_H) 23 | check_include_files("sys/dvdio.h" HAVE_SYS_DVDIO_H) 24 | check_include_files("dlfcn.h" HAVE_DLFCN_H) 25 | check_include_files("dvd.h" HAVE_DVD_H) 26 | check_include_files("errno.h" HAVE_ERRNO_H) 27 | check_include_files("fcntl.h" HAVE_FCNTL_H) 28 | check_include_files("inttypes.h" HAVE_INTTYPES_H) 29 | check_include_files("io.h" HAVE_IO_H) 30 | check_include_files("memory.h" HAVE_MEMORY_H) 31 | check_include_files("pwd.h" HAVE_PWD_H) 32 | check_include_files("stdint.h" HAVE_STDINT_H) 33 | check_include_files("stdlib.h" HAVE_STDLIB_H) 34 | check_include_files("strings.h" HAVE_STRINGS_H) 35 | check_include_files("string.h" HAVE_STRING_H) 36 | check_include_files("sys/ioctl.h" HAVE_SYS_IOCTL_H) 37 | check_include_files("sys/param.h" HAVE_SYS_PARAM_H) 38 | check_include_files("sys/scsi/impl/uscsi.h" HAVE_SYS_SCSI_IMPL_USCSI_H) 39 | check_include_files("sys/scsi/scsi_types.h" HAVE_SYS_SCSI_SCSI_TYPES_H) 40 | check_include_files("sys/stat.h" HAVE_SYS_STAT_H) 41 | check_include_files("sys/types.h" HAVE_SYS_TYPES_H) 42 | check_include_files("sys/uio.h" HAVE_SYS_UIO_H) 43 | check_include_files("unistd.h" HAVE_UNISTD_H) 44 | check_include_files("windows.h" HAVE_WINDOWS_H) 45 | check_include_files("winioctl.h" HAVE_WINIOCTL_H) 46 | 47 | check_file_offset_bits() 48 | 49 | include(CheckFunctionExists) 50 | check_function_exists("mkdir" HAVE_MKDIR_F) 51 | if(NOT HAVE_MKDIR_F OR MSVC) 52 | set(HAVE_BROKEN_MKDIR 1) 53 | endif() 54 | 55 | set(CMAKE_EXTRA_INCLUDE_FILES "sys/cdio.h") 56 | check_type_size(dvd_struct DVD_STRUCT) 57 | if(HAVE_DVD_STRUCT) 58 | set(BSD_DVD_STRUCT 1) 59 | set(LINUX_DVD_STRUCT 1) 60 | set(OPENBSD_DVD_STRUCT 1) 61 | endif() 62 | set(HAVE_DVD_STRUCT) 63 | 64 | set(CMAKE_EXTRA_INCLUDE_FILES "sys/dvdio.h") 65 | check_type_size(dvd_struct DVD_STRUCT) 66 | if(HAVE_DVD_STRUCT) 67 | set(BSD_DVD_STRUCT 1) 68 | set(LINUX_DVD_STRUCT 1) 69 | endif() 70 | unset(HAVE_DVD_STRUCT) 71 | 72 | set(CMAKE_EXTRA_INCLUDE_FILES "linux/cdrom.h") 73 | check_type_size(dvd_struct DVD_STRUCT) 74 | if(HAVE_DVD_STRUCT) 75 | set(LINUX_DVD_STRUCT 1) 76 | endif() 77 | unset(HAVE_DVD_STRUCT) 78 | 79 | check_type_size(size_t SIZE_T) 80 | if(NOT HAVE_SIZE_T) 81 | if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) 82 | set(size_t "uint64_t") 83 | else("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) 84 | set(size_t "uint32_t") 85 | endif("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) 86 | endif(NOT HAVE_SIZE_T) 87 | 88 | if(LINUX_DVD_STRUCT) 89 | set(HAVE_LINUX_DVD_STRUCT 1) 90 | if(OPENBSD_DVD_STRUCT) 91 | set(HAVE_OPENBSD_DVD_STRUCT 1) 92 | endif() 93 | elseif(BSD_DVD_STRUCT) 94 | set(HAVE_BSD_DVD_STRUCT 1) 95 | endif() 96 | 97 | set(LT_OBJDIR "./libs") 98 | set(PACKAGE ${PROJECT_NAME}) 99 | set(PACKAGE_NAME ${PROJECT_NAME}) 100 | set(PACKAGE_STRING "${PROJECT_NAME} ${LIBDVDCSS_VERSION}") 101 | set(PACKAGE_TARNAME ${PROJECT_NAME}) 102 | set(PACKAGE_URL "https://www.videolan.org/developers/libdvdcss.html") 103 | set(PACKAGE_VERSION ${LIBDVDCSS_VERSION}) 104 | set(STDC_HEADERS 1) 105 | set(SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT 1) 106 | set(SUPPORT_FLAG_VISIBILITY 1) 107 | set(VERSION ${LIBDVDCSS_VERSION}) 108 | set(_WIN32_IE "0x0600") 109 | 110 | configure_file(${CMAKE_SOURCE_DIR}/config.h.cm ${CMAKE_BINARY_DIR}/config.h) 111 | configure_file(${CMAKE_SOURCE_DIR}/src/dvdcss/version.h.in ${CMAKE_BINARY_DIR}/version.h @ONLY) 112 | unset(size_t) 113 | 114 | add_library(${PROJECT_NAME} 115 | src/common.h 116 | src/css.c 117 | src/css.h 118 | src/csstables.h 119 | src/device.c 120 | src/device.h 121 | src/error.c 122 | src/ioctl.c 123 | src/ioctl.h 124 | src/libdvdcss.c 125 | src/libdvdcss.h 126 | src/dvdcss/dvdcss.h 127 | ) 128 | add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) 129 | target_include_directories(${PROJECT_NAME} 130 | PRIVATE 131 | $ 132 | INTERFACE 133 | $ 134 | ) 135 | if(MSVC) 136 | target_compile_definitions(${PROJECT_NAME} 137 | PRIVATE 138 | LIBDVDCSS_EXPORTS 139 | _CRT_SECURE_NO_WARNINGS 140 | PATH_MAX=1024 141 | ) 142 | if(CMAKE_SYSTEM_NAME STREQUAL WindowsStore) 143 | enable_language(CXX) 144 | target_sources(${PROJECT_NAME} 145 | PRIVATE 146 | ${CMAKE_SOURCE_DIR}/msvc/uwpapi.cpp 147 | ) 148 | set_source_files_properties(${CMAKE_SOURCE_DIR}/msvc/uwpapi.cpp PROPERTIES COMPILE_FLAGS "/TP /ZW") 149 | endif() 150 | endif() 151 | 152 | include(CMakePackageConfigHelpers) 153 | write_basic_package_version_file( 154 | ${CMAKE_CURRENT_BINARY_DIR}/dvdcss-config-version.cmake 155 | VERSION ${LIBDVDCSS_VERSION} 156 | COMPATIBILITY AnyNewerVersion 157 | ) 158 | 159 | install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME} 160 | RUNTIME DESTINATION bin 161 | ARCHIVE DESTINATION lib 162 | LIBRARY DESTINATION lib) 163 | 164 | 165 | install(FILES 166 | ${CMAKE_CURRENT_SOURCE_DIR}/src/dvdcss/dvdcss.h 167 | ${CMAKE_CURRENT_BINARY_DIR}/version.h 168 | DESTINATION include/dvdcss) 169 | 170 | install(EXPORT ${PROJECT_NAME} 171 | FILE 172 | dvdcss.cmake 173 | NAMESPACE 174 | dvdcss:: 175 | DESTINATION 176 | lib/cmake/dvdcss 177 | ) 178 | install( 179 | FILES 180 | cmake/dvdcss-config.cmake 181 | ${CMAKE_CURRENT_BINARY_DIR}/dvdcss-config-version.cmake 182 | DESTINATION 183 | lib/cmake/dvdcss 184 | ) 185 | if(MSVC AND BUILD_SHARED_LIBS) 186 | install(FILES 187 | $ 188 | DESTINATION lib 189 | ) 190 | endif() 191 | export(TARGETS dvdcss 192 | FILE 193 | ${CMAKE_CURRENT_BINARY_DIR}/dvdcss-config.cmake 194 | NAMESPACE dvdcss:: 195 | ) 196 | -------------------------------------------------------------------------------- /libdvdcss.spec.in: -------------------------------------------------------------------------------- 1 | %define name @PACKAGE_NAME@ 2 | %define version @PACKAGE_VERSION@ 3 | %define release 1 4 | 5 | %define major 2 6 | %define libname %{name}%{major} 7 | 8 | %define buildfor_rh9 %([[ -e /etc/mandrake-release ]] && echo 0 || echo 1) 9 | 10 | %if %buildfor_rh9 11 | # some mdk macros that do not exist in rh 12 | %define configure2_5x %configure 13 | %define make %__make 14 | %define makeinstall_std %makeinstall 15 | # adjust define for Red Hat. 16 | %endif 17 | 18 | 19 | Name: %{name} 20 | Version: %{version} 21 | Release: %{release}%{?dist} 22 | Summary: Library for accessing DVDs like block devices with transparent decryption 23 | Source: %{name}-%{version}.tar.bz2 24 | License: GPL 25 | Group: System/Libraries 26 | URL: @PACKAGE_URL@ 27 | Packager: Yves Duret 28 | BuildRoot: %_tmppath/%name-%version-%release-root 29 | Conflicts: libdvdcss0.0.1, libdvdcss0.0.2 30 | 31 | %description 32 | libdvdcss is a simple library designed for accessing DVDs like a block device 33 | without having to bother about the decryption. The important features are: 34 | * Portability: Currently supported platforms are GNU/Linux, FreeBSD, NetBSD, 35 | OpenBSD, Haiku, Mac OS X, Solaris, QNX, OS/2, and Windows 2000 or later. 36 | * Adaptability: Unlike most similar projects, libdvdcss does not require the 37 | region of your drive to be set and will try its best to read from the disc 38 | even in the case of a region mismatch. 39 | * Simplicity: A DVD player can be built around the libdvdcss API using no 40 | more than 4 or 5 library calls. 41 | 42 | %package -n %{libname} 43 | Summary: Library for accessing DVDs like block devices with transparent decryption 44 | Group: System/Libraries 45 | Provides: %name = %version-%release 46 | 47 | %description -n %{libname} 48 | libdvdcss is a simple library designed for accessing DVDs like a block device 49 | without having to bother about the decryption. The important features are: 50 | * Portability: Currently supported platforms are GNU/Linux, FreeBSD, NetBSD, 51 | OpenBSD, Haiku, Mac OS X, Solaris, QNX, OS/2, and Windows 2000 or later. 52 | * Adaptability: Unlike most similar projects, libdvdcss does not require the 53 | region of your drive to be set and will try its best to read from the disc 54 | even in the case of a region mismatch. 55 | * Simplicity: A DVD player can be built around the libdvdcss API using no 56 | more than 4 or 5 library calls. 57 | 58 | %package -n %{libname}-devel 59 | Summary: Development tools for programs which will use the %{name} library 60 | Group: Development/C 61 | Requires: %{libname} = %version-%release 62 | Provides: %{name}-devel = %version-%release 63 | 64 | %description -n %{libname}-devel 65 | The %{name}-devel package includes the header files and static libraries 66 | necessary for developing programs which will manipulate DVDs files using 67 | the %{name} library. 68 | 69 | If you are going to develop programs which will manipulate DVDs, you 70 | should install %{name}-devel. You will also need to have the %{name} 71 | package installed. 72 | 73 | %prep 74 | %setup -q 75 | 76 | %build 77 | %configure2_5x 78 | %make 79 | 80 | %install 81 | %makeinstall_std 82 | 83 | %clean 84 | [ %buildroot != "/" ] && rm -Rf %buildroot 85 | 86 | %post -n %{libname} -p /sbin/ldconfig 87 | 88 | %postun -n %{libname} -p /sbin/ldconfig 89 | 90 | %files -n %{libname} 91 | %defattr(-,root,root) 92 | %doc AUTHORS COPYING NEWS 93 | %{_docdir}/libdvdcss 94 | %{_libdir}/*.so.* 95 | 96 | %files -n %{libname}-devel 97 | %defattr(-,root,root) 98 | %doc ChangeLog COPYING 99 | %{_libdir}/*.a 100 | %{_libdir}/*.so 101 | %{_libdir}/*.la 102 | %{_libdir}/pkgconfig/* 103 | %{_includedir}/* 104 | 105 | %changelog 106 | * Mon Jul 11 2005 Sam Hocevar 1.2.9-1 107 | - new upstream release 108 | 109 | * Tue Jul 29 2003 Sam Hocevar 1.2.8-1 110 | - new upstream release 111 | 112 | * Fri Jun 13 2003 Sam Hocevar 1.2.7-1 113 | - new upstream release 114 | - key cache activated by default 115 | 116 | * Mon Mar 10 2003 Alexis de Lattre 1.2.6-1 117 | - new upstream release 118 | - small bug fixes 119 | 120 | * Tue Jan 28 2003 Sam Hocevar 1.2.5-1 121 | - new upstream release 122 | - improved robustness in case of read errors 123 | - key cache support 124 | - added more macros to fix Red Hat build 125 | 126 | * Mon Nov 18 2002 Alexis de Lattre 1.2.4-2 127 | - Changes in .spec file for Red Hat and RPM 4.1 128 | 129 | * Thu Nov 14 2002 Alexis de Lattre 1.2.4-1 130 | - new upstream release 131 | - fixes for Win32 132 | 133 | * Sun Oct 13 2002 Sam Hocevar 1.2.3-1 134 | - new upstream release 135 | - fix for drives not allowing to read their disc key 136 | 137 | * Sat Aug 10 2002 Sam Hocevar 1.2.2-1 138 | - new upstream release 139 | - even more fixes for the disc/drive region mismatch problem 140 | 141 | * Sun Jun 02 2002 Sam Hocevar 1.2.1-1 142 | - new upstream release 143 | - fix for a crash on disc/drive region mismatch 144 | 145 | * Mon May 20 2002 Sam Hocevar 1.2.0-1 146 | - new upstream release 147 | - weird libxalf dependency is gone 148 | 149 | * Sun Apr 07 2002 Yves Duret 1.1.1-2plf 150 | - major version is 2 (aka guillaume sux). 151 | - spec clean up: do not rm in %%prep, %%buildroot, %%makeinstall_std, %%provides %%version-%%release 152 | - added doc in devel 153 | - sync with the CVS one (%%description,%%files, conflicts). 154 | - fix URL 155 | 156 | * Sat Apr 06 2002 Guillaume Rousse 1.1.1-1plf 157 | - 1.1.1 158 | 159 | * Wed Jan 30 2002 Guillaume Rousse 1.0.0-3plf 160 | - new plf extension 161 | 162 | * Wed Dec 05 2001 Guillaume Rousse 1.0.0-3mdk 163 | - removed conflict 164 | 165 | * Tue Dec 04 2001 Guillaume Rousse 1.0.0-2mdk 166 | - contributed to PLF by Yves Duret 167 | - Conflicts: libdvdcss-ogle 168 | - more doc files 169 | - no doc file for devel package 170 | 171 | * Fri Nov 30 2001 Yves Duret 1.0.0-1mdk 172 | - version 1.0.0 173 | 174 | * Thu Aug 23 2001 Yves Duret 0.0.3-1mdk 175 | - version 0.0.3 176 | 177 | * Mon Aug 13 2001 Yves Duret 0.0.2-1mdk 178 | - version 0.0.2 179 | 180 | * Tue Jun 19 2001 Yves Duret 0.0.1-1mdk 181 | - first release and first mdk release 182 | -------------------------------------------------------------------------------- /msvc/libdvdcss.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | 15 | 16 | {50F2BF62-8520-4B37-97DD-578EA282EC04} 17 | 18 | 19 | 20 | StaticLibrary 21 | v110 22 | false 23 | MultiByte 24 | 25 | 26 | StaticLibrary 27 | v110 28 | false 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | .\Release\ 45 | .\Release\ 46 | false 47 | 48 | 49 | .\Debug\ 50 | .\Debug\ 51 | true 52 | 53 | 54 | 55 | MultiThreaded 56 | Default 57 | true 58 | true 59 | MaxSpeed 60 | true 61 | Level3 62 | .;%(AdditionalIncludeDirectories) 63 | NDEBUG;WIN32;_LIB;PATH_MAX=2048;%(PreprocessorDefinitions) 64 | .\Release\ 65 | .\Release\libdvdcss.pch 66 | .\Release\ 67 | .\Release\ 68 | 69 | 70 | 0x0409 71 | NDEBUG;%(PreprocessorDefinitions) 72 | 73 | 74 | true 75 | .\Release\libdvdcss.bsc 76 | 77 | 78 | true 79 | .\Release\libdvdcss.lib 80 | 81 | 82 | 83 | 84 | MultiThreadedDebug 85 | Default 86 | false 87 | Disabled 88 | true 89 | Level3 90 | true 91 | EditAndContinue 92 | .;%(AdditionalIncludeDirectories) 93 | _DEBUG;WIN32;_LIB;PATH_MAX=2048;%(PreprocessorDefinitions) 94 | .\Debug\ 95 | .\Debug\libdvdcss.pch 96 | .\Debug\ 97 | .\Debug\ 98 | EnableFastChecks 99 | 100 | 101 | 0x0409 102 | _DEBUG;%(PreprocessorDefinitions) 103 | 104 | 105 | true 106 | .\Debug\libdvdcss.bsc 107 | 108 | 109 | true 110 | .\Debug\libdvdcss.lib 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | dnl library version number 2 | m4_define([dvdcss_major], 1) 3 | m4_define([dvdcss_minor], 4) 4 | m4_define([dvdcss_micro], 3) 5 | m4_define([dvdcss_version],[dvdcss_major.dvdcss_minor.dvdcss_micro]) 6 | 7 | AC_INIT(libdvdcss, dvdcss_version, , , https://www.videolan.org/developers/libdvdcss.html) 8 | AC_CONFIG_SRCDIR([src/libdvdcss.c]) 9 | 10 | AC_PREREQ(2.50) 11 | AC_CANONICAL_HOST 12 | 13 | AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip subdir-objects]) 14 | AM_MAINTAINER_MODE([enable]) 15 | dnl Enable silent rules only when available (automake 1.11 or later). 16 | m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) 17 | 18 | LT_INIT([win32-dll]) 19 | 20 | AC_CONFIG_HEADER(config.h) 21 | AC_CONFIG_MACRO_DIR([m4]) 22 | 23 | dnl The libtool version numbers (DVDCSS_LT_*); Don't even think about faking this! 24 | dnl 25 | dnl immediately before every release do: 26 | dnl =================================== 27 | dnl if (the interface is totally unchanged from previous release) 28 | dnl DVDCSS_LT_REVISION ++; 29 | dnl else { /* interfaces have been added, removed or changed */ 30 | dnl DVDCSS_LT_REVISION = 0; 31 | dnl DVDCSS_LT_CURRENT ++; 32 | dnl if (any interfaces have been _added_ since last release) 33 | dnl AGE ++; 34 | dnl if (any interfaces have been _removed_ or _incompatibly changed_) 35 | dnl AGE = 0; 36 | dnl } 37 | dnl 38 | dnl If you want to know more about what you are doing, here are some details: 39 | dnl * DVDCSS_LT_CURRENT is the current API version 40 | dnl * DVDCSS_LT_REVISION is an internal revision number which is increased when the API 41 | dnl itself did not change 42 | dnl * DVDCSS_LT_AGE is the number of previous API versions still supported by this library 43 | dnl * libtool has its own numbering scheme, because local library numbering schemes 44 | dnl are platform dependent 45 | dnl * in Linux, the library will be named 46 | dnl libname.so.(DVDCSS_LT_CURRENT - DVDCSS_LT_AGE).DVDCSS_LT_AGE.DVDCSS_LT_REVISION 47 | 48 | DVDCSS_LT_CURRENT=4 49 | DVDCSS_LT_AGE=2 50 | DVDCSS_LT_REVISION=0 51 | 52 | AC_SUBST([DVDCSS_LTVERSION], [$DVDCSS_LT_CURRENT:$DVDCSS_LT_REVISION:$DVDCSS_LT_AGE]) 53 | 54 | AC_PROG_CC 55 | AC_HEADER_STDC 56 | 57 | AC_C_CONST 58 | AC_C_INLINE 59 | AC_TYPE_SIZE_T 60 | 61 | AC_CHECK_HEADERS([unistd.h sys/param.h sys/uio.h pwd.h]dnl 62 | [errno.h sys/types.h sys/stat.h fcntl.h io.h]) 63 | 64 | AC_CHECK_DECL([O_BINARY], [], 65 | [AC_DEFINE([O_BINARY], [0], [Define O_BINARY if missing])], 66 | [ 67 | #if HAVE_SYS_TYPES_H 68 | # include 69 | #endif 70 | #if HAVE_SYS_STAT_H 71 | # include 72 | #endif 73 | #if HAVE_FCNTL_H 74 | # include 75 | #endif 76 | ]) 77 | 78 | AC_SYS_LARGEFILE 79 | 80 | AC_CACHE_CHECK( 81 | [for posix mkdir()], 82 | [css_cv_mkdir_posix], [ 83 | AC_COMPILE_IFELSE([AC_LANG_SOURCE([ 84 | #ifdef HAVE_IO_H 85 | # include 86 | #endif 87 | #ifdef HAVE_SYS_STAT_H 88 | # include 89 | #endif 90 | #ifdef HAVE_SYS_TYPES_H 91 | # include 92 | #endif 93 | 94 | int mkdir(const char *path, mode_t mode); 95 | ]) 96 | ], 97 | [css_cv_mkdir_posix=yes], 98 | [css_cv_mkdir_posix=no]) 99 | ]) 100 | 101 | AS_IF([test "$css_cv_mkdir_posix" = "no"], [ 102 | AC_DEFINE([HAVE_BROKEN_MKDIR], 1, [Define if you have a broken mkdir]) 103 | ]) 104 | 105 | dnl 106 | dnl Check the operating system 107 | dnl 108 | 109 | case x"${host_os}" in 110 | xdarwin*) 111 | CFLAGS="${CFLAGS} -no-cpp-precomp" 112 | ;; 113 | x*cygwin* | x*msys*) 114 | CFLAGS="${CFLAGS} -mwin32" 115 | AC_DEFINE([_WIN32_IE], 0x0501, [Define to '0x0501' for IE 5.01 (and shell) APIs.]) 116 | ;; 117 | xos2*) 118 | LDFLAGS="-Zbin-files" 119 | ;; 120 | x*msvc*) 121 | SYS_MSVC=1 122 | AC_DEFINE([_WIN32_IE], 0x0501, [Define to '0x0501' for IE 5.01 (and shell) APIs.]) 123 | ;; 124 | x*mingw* | x*wince* | x*mingwce*) 125 | AC_DEFINE([_WIN32_IE], 0x0501, [Define to '0x0501' for IE 5.01 (and shell) APIs.]) 126 | ;; 127 | x*) 128 | ;; 129 | esac 130 | 131 | dnl 132 | dnl libdvdcss: check for DVD ioctls 133 | dnl 134 | 135 | dnl default is no 136 | CAN_BUILD_LIBDVDCSS=0 137 | 138 | dnl for windoze 139 | AC_CHECK_HEADERS(windows.h,[ 140 | AC_CHECK_HEADERS(winioctl.h,[ 141 | CAN_BUILD_LIBDVDCSS=1 142 | ],,[ 143 | #include 144 | ]) 145 | ]) 146 | 147 | dnl for Unix 148 | AC_CHECK_HEADERS(sys/ioctl.h,[ 149 | CAN_BUILD_LIBDVDCSS=1 150 | AC_CHECK_HEADERS(sys/cdio.h sys/dvdio.h linux/cdrom.h dvd.h) 151 | BSD_DVD_STRUCT=0 152 | LINUX_DVD_STRUCT=0 153 | OPENBSD_DVD_STRUCT=0 154 | dnl 155 | dnl Old FreeBSD: sys/cdio.h 156 | dnl 157 | AC_EGREP_HEADER(dvd_struct,sys/cdio.h,[ 158 | AC_DEFINE(DVD_STRUCT_IN_SYS_CDIO_H, 1, 159 | Define if defines dvd_struct.) 160 | AC_EGREP_HEADER(struct dvd_struct,sys/cdio.h,[ 161 | BSD_DVD_STRUCT=1],[LINUX_DVD_STRUCT=1; OPENBSD_DVD_STRUCT=1]) 162 | ]) 163 | dnl 164 | dnl Newer FreeBSD: sys/dvdio.h 165 | dnl 166 | AC_EGREP_HEADER(dvd_struct,sys/dvdio.h,[ 167 | AC_DEFINE(DVD_STRUCT_IN_SYS_DVDIO_H, 1, 168 | Define if defines dvd_struct.) 169 | AC_EGREP_HEADER(struct dvd_struct,sys/dvdio.h,[ 170 | BSD_DVD_STRUCT=1],[LINUX_DVD_STRUCT=1]) 171 | ]) 172 | dnl 173 | dnl Linux: linux/cdrom.h 174 | dnl 175 | AC_EGREP_HEADER(dvd_struct,linux/cdrom.h,[ 176 | AC_DEFINE(DVD_STRUCT_IN_LINUX_CDROM_H, 1, 177 | Define if defines DVD_STRUCT.) 178 | LINUX_DVD_STRUCT=1 179 | ]) 180 | dnl 181 | dnl Solaris: sys/scsi/scsi_types.h, sys/scsi/impl/uscsi.h 182 | dnl 183 | solaris_uscsi=yes 184 | AC_CHECK_HEADERS([sys/scsi/scsi_types.h sys/scsi/impl/uscsi.h], [], 185 | [solaris_uscsi=no; break;]) 186 | AS_IF([test "$solaris_uscsi" = "yes"], [ 187 | AC_DEFINE(SOLARIS_USCSI, 1, Have userspace SCSI headers.) 188 | ]) 189 | dnl 190 | dnl Darwin 191 | dnl 192 | AC_CHECK_HEADER(IOKit/storage/IODVDMediaBSDClient.h,[ 193 | AC_DEFINE(DARWIN_DVD_IOCTL, 1, Have IOKit DVD IOCTL headers) 194 | DVDCSS_LDFLAGS="-Wl,-framework -Wl,CoreFoundation -Wl,-framework -Wl,IOKit" 195 | ]) 196 | dnl 197 | dnl Final tests to check what was detected 198 | dnl 199 | if test x$LINUX_DVD_STRUCT = x1; then 200 | AC_DEFINE(HAVE_LINUX_DVD_STRUCT, 1, 201 | Define if Linux-like dvd_struct is defined.) 202 | if test x$OPENBSD_DVD_STRUCT = x1; then 203 | AC_DEFINE(HAVE_OPENBSD_DVD_STRUCT, 1, 204 | Define if OpenBSD-like dvd_struct is defined.) 205 | fi 206 | else 207 | if test x$BSD_DVD_STRUCT = x1; then 208 | AC_DEFINE(HAVE_BSD_DVD_STRUCT, 1, 209 | Define if FreeBSD-like dvd_struct is defined.) 210 | fi 211 | fi 212 | ]) 213 | 214 | CC_CHECK_CFLAGS_APPEND([-Wall -Wextra]) 215 | CC_FLAG_VISIBILITY([ 216 | CC_ATTRIBUTE_VISIBILITY([default], [ 217 | CFLAGS="${CFLAGS} -fvisibility=hidden" 218 | ]) 219 | ]) 220 | 221 | AM_CONDITIONAL(SYS_MSVC, test "${SYS_MSVC}" = "1") 222 | 223 | AC_ARG_ENABLE([doc], 224 | AS_HELP_STRING([--disable-doc], [Disable building (with Doxygen) and installing API documentation @<:@default=auto@:@>])) 225 | 226 | AS_IF([test "x$enable_doc" != "xno"], [ 227 | AC_PATH_PROG([DOXYGEN], [doxygen]) 228 | ]) 229 | 230 | AS_IF([test "x$DOXYGEN" = "x"], [ 231 | AS_IF([test "x$enable_doc" = "xyes"], [ 232 | AC_MSG_ERROR([You need Doxygen to build API documentation]) 233 | ]) 234 | ]) 235 | AM_CONDITIONAL([APIDOC], [test "x$DOXYGEN" != "x"]) 236 | 237 | AC_PATH_PROG([GIT], [git]) 238 | AM_CONDITIONAL([GIT], [test "x$GIT" != "x"]) 239 | 240 | dnl export library version number 241 | DVDCSS_VERSION_MAJOR=dvdcss_major() 242 | DVDCSS_VERSION_MINOR=dvdcss_minor() 243 | DVDCSS_VERSION_MICRO=dvdcss_micro() 244 | AC_SUBST(DVDCSS_VERSION_MAJOR) 245 | AC_SUBST(DVDCSS_VERSION_MINOR) 246 | AC_SUBST(DVDCSS_VERSION_MICRO) 247 | 248 | AC_SUBST(DVDCSS_LDFLAGS) 249 | AC_OUTPUT([ 250 | Makefile 251 | libdvdcss.spec 252 | doc/doxygen.cfg 253 | src/libdvdcss.pc 254 | src/dvdcss/version.h 255 | ]) 256 | -------------------------------------------------------------------------------- /test/dvd_region.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Set / inspect region settings on a DVD drive. This is most interesting 3 | * on a RPC Phase-2 drive, of course. 4 | * 5 | * Usage: dvd_region [ -d device ] [ [ -s ] [ -r region ] ] 6 | * 7 | * Based on code from Jens Axboe . 8 | * 9 | * FIXME: This code does _not_ work yet. 10 | */ 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | #include "config.h" 21 | #include "common.h" 22 | #include "ioctl.h" 23 | #include "libdvdcss.h" 24 | 25 | /* On non-Linux platforms static functions from ioctl.c are used. */ 26 | #include "ioctl.c" 27 | 28 | #define DEFAULT_DEVICE "/dev/dvd" 29 | 30 | /***************************************************************************** 31 | * ioctl_SendRPC: set RPC status for the drive 32 | *****************************************************************************/ 33 | static int ioctl_SendRPC( int i_fd, int i_pdrc ) 34 | { 35 | int i_ret; 36 | 37 | /* Shut up warnings about unused parameters. */ 38 | (void)i_fd; 39 | (void)i_pdrc; 40 | 41 | #if defined( HAVE_LINUX_DVD_STRUCT ) && defined( DVD_HOST_SEND_RPC_STATE ) 42 | dvd_authinfo auth_info = { 0 }; 43 | 44 | auth_info.type = DVD_HOST_SEND_RPC_STATE; 45 | auth_info.hrpcs.pdrc = i_pdrc; 46 | 47 | i_ret = ioctl( i_fd, DVD_AUTH, &auth_info ); 48 | 49 | #elif defined( HAVE_LINUX_DVD_STRUCT ) 50 | /* FIXME: OpenBSD doesn't know this */ 51 | i_ret = -1; 52 | 53 | #elif defined( HAVE_BSD_DVD_STRUCT ) 54 | struct dvd_authinfo auth_info = { 0 }; 55 | 56 | auth_info.format = DVD_SEND_RPC; 57 | auth_info.region = i_pdrc; 58 | 59 | i_ret = ioctl( i_fd, DVDIOCSENDKEY, &auth_info ); 60 | 61 | #elif defined( __HAIKU__ ) 62 | INIT_RDC( GPCMD_SEND_KEY, 8 ); 63 | 64 | rdc.command[ 10 ] = DVD_SEND_RPC; 65 | 66 | p_buffer[ 1 ] = 6; 67 | p_buffer[ 4 ] = i_pdrc; 68 | 69 | i_ret = ioctl( i_fd, B_RAW_DEVICE_COMMAND, &rdc, sizeof(rdc) ); 70 | 71 | #elif defined( SOLARIS_USCSI ) 72 | INIT_USCSI( GPCMD_SEND_KEY, 8 ); 73 | 74 | rs_cdb.cdb_opaque[ 10 ] = DVD_SEND_RPC; 75 | 76 | p_buffer[ 1 ] = 6; 77 | p_buffer[ 4 ] = i_pdrc; 78 | 79 | i_ret = SolarisSendUSCSI( i_fd, &sc ); 80 | 81 | if( i_ret < 0 || sc.uscsi_status ) 82 | { 83 | i_ret = -1; 84 | } 85 | 86 | #elif defined( DARWIN_DVD_IOCTL ) 87 | INIT_DVDIOCTL( dk_dvd_send_key_t, DVDRegionPlaybackControlInfo, 88 | kDVDKeyFormatSetRegion ); 89 | 90 | dvd.keyClass = kDVDKeyClassCSS_CPPM_CPRM; 91 | dvdbs.driveRegion = i_pdrc; 92 | 93 | i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd ); 94 | 95 | #elif defined( _WIN32 ) 96 | DWORD tmp; 97 | SCSI_PASS_THROUGH_DIRECT sptd = { 0 }; 98 | uint8_t p_buffer[8]; 99 | sptd.Length = sizeof( SCSI_PASS_THROUGH_DIRECT ); 100 | sptd.DataBuffer = p_buffer; 101 | sptd.DataTransferLength = sizeof( p_buffer ); 102 | WinInitSPTD( &sptd, GPCMD_SEND_KEY ); 103 | 104 | sptd.Cdb[ 10 ] = DVD_SEND_RPC; 105 | 106 | p_buffer[ 1 ] = 6; 107 | p_buffer[ 4 ] = i_pdrc; 108 | 109 | i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_SCSI_PASS_THROUGH_DIRECT, 110 | &sptd, sizeof( SCSI_PASS_THROUGH_DIRECT ), 111 | &sptd, sizeof( SCSI_PASS_THROUGH_DIRECT ), 112 | &tmp, NULL ) ? 0 : -1; 113 | 114 | #elif defined( __QNXNTO__ ) 115 | 116 | INIT_CPT( GPCMD_SEND_KEY, 8 ); 117 | 118 | p_cpt->cam_cdb[ 10 ] = DVD_SEND_RPC; 119 | 120 | p_buffer[ 1 ] = 6; 121 | p_buffer[ 4 ] = i_pdrc; 122 | 123 | i_ret = devctl(i_fd, DCMD_CAM_PASS_THRU, p_cpt, structSize, NULL); 124 | 125 | #elif defined( __OS2__ ) 126 | INIT_SSC( GPCMD_SEND_KEY, 8 ); 127 | 128 | sdc.command[ 10 ] = DVD_SEND_RPC; 129 | 130 | p_buffer[ 1 ] = 6; 131 | p_buffer[ 4 ] = i_pdrc; 132 | 133 | i_ret = DosDevIOCtl( i_fd, IOCTL_CDROMDISK, CDROMDISK_EXECMD, 134 | &sdc, sizeof(sdc), &ulParamLen, 135 | p_buffer, sizeof(p_buffer), &ulDataLen ); 136 | 137 | #else 138 | # error "DVD ioctls are unavailable on this system" 139 | 140 | #endif 141 | return i_ret; 142 | } 143 | 144 | static int set_region(int fd, int region) 145 | { 146 | int ret, region_mask; 147 | 148 | if(region > 8 || region <= 0) { 149 | printf("Invalid region( %d)\n", region); 150 | return 1; 151 | } 152 | printf("Setting drive region can only be done a finite " 153 | "number of times, press Ctrl-C now to cancel!\n"); 154 | /* Discard returned character, just wait for any key as confirmation. */ 155 | (void) getchar(); 156 | 157 | region_mask = 0xff & ~(1 << (region - 1)); 158 | printf("Setting region to %d( %x)\n", region, region_mask); 159 | if( (ret = ioctl_SendRPC(fd, region_mask)) < 0) { 160 | perror("dvd_region"); 161 | return ret; 162 | } 163 | 164 | return 0; 165 | } 166 | 167 | static int print_region(int fd) 168 | { 169 | int type, region_mask, rpc_scheme; 170 | int region = 1; 171 | int ret; 172 | 173 | printf("Drive region info:\n"); 174 | 175 | if( (ret = ioctl_ReportRPC(fd, &type, ®ion_mask, &rpc_scheme)) < 0) { 176 | perror("dvd_region"); 177 | return ret; 178 | } 179 | 180 | printf("Type: "); 181 | switch( type ) { 182 | case 0: 183 | printf("No drive region setting\n"); 184 | break; 185 | case 1: 186 | printf("Drive region is set\n"); 187 | break; 188 | case 2: 189 | printf("Drive region is set, with additional " 190 | "restrictions required to make a change\n"); 191 | break; 192 | case 3: 193 | printf("Drive region has been set permanently, but " 194 | "may be reset by the vendor if necessary\n"); 195 | break; 196 | default: 197 | printf("Invalid( %x)\n", type); 198 | break; 199 | } 200 | 201 | printf("Region: "); 202 | if( region_mask) 203 | while(region_mask) { 204 | if( !(region_mask & 1) ) 205 | printf("%d playable\n", region); 206 | region++; 207 | region_mask >>= 1; 208 | } 209 | else 210 | printf("non-RPC( all)\n"); 211 | 212 | printf("RPC Scheme: "); 213 | switch( rpc_scheme ) { 214 | case 0: 215 | printf("The Logical Unit does not enforce Regional " 216 | "Playback Control (RPC).\n"); 217 | break; 218 | case 1: 219 | printf("The Logical Unit _shall_ adhere to the " 220 | "specification and all requirements of the " 221 | "Content Scrambling System (CSS) license " 222 | "agreement concerning RPC.\n"); 223 | break; 224 | default: 225 | printf("Reserved( %x)\n", rpc_scheme); 226 | } 227 | 228 | return 0; 229 | } 230 | 231 | static void usage(void) 232 | { 233 | fprintf( stderr, 234 | "Usage: dvd_region [ -d device ] [ [ -s ] [ -r region ] ]\n" ); 235 | } 236 | 237 | int main(int argc, char *argv[]) 238 | { 239 | char device_name[FILENAME_MAX], c, set, region = 0; 240 | int ret; 241 | dvdcss_t dvdcss; 242 | 243 | strcpy(device_name, DEFAULT_DEVICE); 244 | set = 0; 245 | while( (c = getopt(argc, argv, "d:sr:h?")) != EOF ) { 246 | switch( c ) { 247 | case 'd': 248 | strncpy(device_name, optarg, FILENAME_MAX - 1); 249 | break; 250 | case 's': 251 | set = 1; 252 | break; 253 | case 'r': 254 | region = strtoul(optarg, NULL, 10); 255 | printf("region %d\n", region); 256 | break; 257 | case 'h': 258 | case '?': 259 | default: 260 | usage(); 261 | return -1; 262 | break; 263 | } 264 | } 265 | 266 | if( optind != argc ) { 267 | fprintf(stderr, "Unknown argument\n"); 268 | usage(); 269 | return -1; 270 | } 271 | 272 | if( !(dvdcss = dvdcss_open(device_name)) ) { 273 | usage(); 274 | return 1; 275 | } 276 | 277 | { 278 | int copyright; 279 | ret = ioctl_ReadCopyright( dvdcss->i_fd, 0, ©right ); 280 | printf( "ret %d, copyright %d\n", ret, copyright ); 281 | } 282 | 283 | if( (ret = print_region(dvdcss->i_fd)) < 0 ) 284 | return ret; 285 | 286 | if( set ) { 287 | if( !region ) { 288 | fprintf( stderr, "you must specify the region!\n" ); 289 | exit(0); 290 | } 291 | 292 | if( (ret = set_region(dvdcss->i_fd, region)) < 0 ) 293 | return ret; 294 | } 295 | 296 | exit( 0 ); 297 | } 298 | -------------------------------------------------------------------------------- /src/ioctl.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * ioctl.h: DVD ioctl replacement function 3 | ***************************************************************************** 4 | * Copyright (C) 1999-2001 VideoLAN 5 | * 6 | * Authors: Sam Hocevar 7 | * 8 | * libdvdcss is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * libdvdcss is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License along 19 | * with libdvdcss; if not, write to the Free Software Foundation, Inc., 20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | *****************************************************************************/ 22 | 23 | #ifndef DVDCSS_IOCTL_H 24 | #define DVDCSS_IOCTL_H 25 | 26 | #include 27 | 28 | int ioctl_ReadCopyright ( int, int, int * ); 29 | int ioctl_ReadDiscKey ( int, const int *, uint8_t * ); 30 | int ioctl_ReadTitleKey ( int, const int *, int, uint8_t * ); 31 | int ioctl_ReportAgid ( int, int * ); 32 | int ioctl_ReportChallenge ( int, const int *, uint8_t * ); 33 | int ioctl_ReportKey1 ( int, const int *, uint8_t * ); 34 | int ioctl_ReportASF ( int, int * ); 35 | int ioctl_InvalidateAgid ( int, int * ); 36 | int ioctl_SendChallenge ( int, const int *, const uint8_t * ); 37 | int ioctl_SendKey2 ( int, const int *, const uint8_t * ); 38 | int ioctl_ReportRPC ( int, int *, int *, int * ); 39 | 40 | #define DVD_DISCKEY_SIZE 2048 41 | 42 | /***************************************************************************** 43 | * Common macros, OS-specific 44 | *****************************************************************************/ 45 | #if defined( __HAIKU__ ) 46 | #define INIT_RDC( TYPE, SIZE ) \ 47 | raw_device_command rdc = { 0 }; \ 48 | uint8_t p_buffer[ (SIZE)+1 ]; \ 49 | rdc.data = (char *)p_buffer; \ 50 | rdc.data_length = (SIZE); \ 51 | BeInitRDC( &rdc, (TYPE) ); 52 | #elif defined( SOLARIS_USCSI ) 53 | #define INIT_USCSI( TYPE, SIZE ) \ 54 | struct uscsi_cmd sc = { 0 }; \ 55 | union scsi_cdb rs_cdb; \ 56 | uint8_t p_buffer[ (SIZE)+1 ]; \ 57 | sc.uscsi_cdb = (caddr_t)&rs_cdb; \ 58 | sc.uscsi_bufaddr = (caddr_t)p_buffer; \ 59 | sc.uscsi_buflen = (SIZE); \ 60 | SolarisInitUSCSI( &sc, (TYPE) ); 61 | #elif defined( DARWIN_DVD_IOCTL ) 62 | #define INIT_DVDIOCTL( DKDVD_TYPE, BUFFER_TYPE, FORMAT ) \ 63 | DKDVD_TYPE dvd = { 0 }; \ 64 | BUFFER_TYPE dvdbs = { 0 }; \ 65 | dvd.format = FORMAT; \ 66 | dvd.buffer = &dvdbs; \ 67 | dvd.bufferLength = sizeof(dvdbs); 68 | #elif defined( __QNXNTO__ ) 69 | #define INIT_CPT( TYPE, SIZE ) \ 70 | CAM_PASS_THRU * p_cpt = { 0 }; \ 71 | uint8_t * p_buffer; \ 72 | int structSize = sizeof( CAM_PASS_THRU ) + (SIZE); \ 73 | p_cpt = (CAM_PASS_THRU *) malloc ( structSize ); \ 74 | p_buffer = (uint8_t *) p_cpt + sizeof( CAM_PASS_THRU ); \ 75 | p_cpt->cam_data_ptr = sizeof( CAM_PASS_THRU ); \ 76 | p_cpt->cam_dxfer_len = (SIZE); \ 77 | QNXInitCPT( p_cpt, (TYPE) ); 78 | #elif defined( __OS2__ ) 79 | #define INIT_SSC( TYPE, SIZE ) \ 80 | struct OS2_ExecSCSICmd sdc = { 0 }; \ 81 | uint8_t p_buffer[ (SIZE) + 1 ] = { 0 }; \ 82 | unsigned long ulParamLen; \ 83 | unsigned long ulDataLen; \ 84 | sdc.data_length = (SIZE); \ 85 | ulParamLen = sizeof(sdc); \ 86 | OS2InitSDC( &sdc, (TYPE) ) 87 | #endif 88 | 89 | /***************************************************************************** 90 | * Additional types, OpenBSD-specific 91 | *****************************************************************************/ 92 | #if defined( HAVE_OPENBSD_DVD_STRUCT ) 93 | typedef union dvd_struct dvd_struct; 94 | typedef union dvd_authinfo dvd_authinfo; 95 | #endif 96 | 97 | /***************************************************************************** 98 | * Various DVD I/O tables 99 | *****************************************************************************/ 100 | /* The generic packet command opcodes for CD/DVD Logical Units, 101 | * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */ 102 | #define GPCMD_READ_DVD_STRUCTURE 0xad 103 | #define GPCMD_REPORT_KEY 0xa4 104 | #define GPCMD_SEND_KEY 0xa3 105 | /* DVD struct types */ 106 | #define DVD_STRUCT_PHYSICAL 0x00 107 | #define DVD_STRUCT_COPYRIGHT 0x01 108 | #define DVD_STRUCT_DISCKEY 0x02 109 | #define DVD_STRUCT_BCA 0x03 110 | #define DVD_STRUCT_MANUFACT 0x04 111 | /* Key formats */ 112 | #define DVD_REPORT_AGID 0x00 113 | #define DVD_REPORT_CHALLENGE 0x01 114 | #define DVD_SEND_CHALLENGE 0x01 115 | #define DVD_REPORT_KEY1 0x02 116 | #define DVD_SEND_KEY2 0x03 117 | #define DVD_REPORT_TITLE_KEY 0x04 118 | #define DVD_REPORT_ASF 0x05 119 | #define DVD_SEND_RPC 0x06 120 | #define DVD_REPORT_RPC 0x08 121 | #define DVDCSS_INVALIDATE_AGID 0x3f 122 | 123 | /***************************************************************************** 124 | * Win32-ioctl-specific 125 | *****************************************************************************/ 126 | #if defined( _WIN32 ) 127 | 128 | #define _WIN32_LEAN_AND_MEAN 129 | #include 130 | #include 131 | 132 | #define IOCTL_DVD_START_SESSION CTL_CODE(FILE_DEVICE_DVD, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS) 133 | #define IOCTL_DVD_READ_KEY CTL_CODE(FILE_DEVICE_DVD, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS) 134 | #define IOCTL_DVD_SEND_KEY CTL_CODE(FILE_DEVICE_DVD, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS) 135 | #define IOCTL_DVD_END_SESSION CTL_CODE(FILE_DEVICE_DVD, 0x0403, METHOD_BUFFERED, FILE_READ_ACCESS) 136 | #define IOCTL_DVD_GET_REGION CTL_CODE(FILE_DEVICE_DVD, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS) 137 | #define IOCTL_DVD_SEND_KEY2 CTL_CODE(FILE_DEVICE_DVD, 0x0406, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) 138 | #define IOCTL_DVD_READ_STRUCTURE CTL_CODE(FILE_DEVICE_DVD, 0x0450, METHOD_BUFFERED, FILE_READ_ACCESS) 139 | #define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(FILE_DEVICE_CONTROLLER, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) 140 | 141 | #define DVD_CHALLENGE_KEY_LENGTH (12 + sizeof(DVD_COPY_PROTECT_KEY)) 142 | #define DVD_BUS_KEY_LENGTH (8 + sizeof(DVD_COPY_PROTECT_KEY)) 143 | #define DVD_TITLE_KEY_LENGTH (8 + sizeof(DVD_COPY_PROTECT_KEY)) 144 | #define DVD_DISK_KEY_LENGTH (2048 + sizeof(DVD_COPY_PROTECT_KEY)) 145 | #define DVD_RPC_KEY_LENGTH (sizeof(DVD_RPC_KEY) + sizeof(DVD_COPY_PROTECT_KEY)) 146 | #define DVD_ASF_LENGTH (sizeof(DVD_ASF) + sizeof(DVD_COPY_PROTECT_KEY)) 147 | 148 | #define DVD_COPYRIGHT_MASK 0x00000040 149 | #define DVD_NOT_COPYRIGHTED 0x00000000 150 | #define DVD_COPYRIGHTED 0x00000040 151 | 152 | #define DVD_SECTOR_PROTECT_MASK 0x00000020 153 | #define DVD_SECTOR_NOT_PROTECTED 0x00000000 154 | #define DVD_SECTOR_PROTECTED 0x00000020 155 | 156 | #define SCSI_IOCTL_DATA_OUT 0 157 | #define SCSI_IOCTL_DATA_IN 1 158 | 159 | typedef ULONG DVD_SESSION_ID, *PDVD_SESSION_ID; 160 | 161 | typedef enum DVD_STRUCTURE_FORMAT { 162 | DvdPhysicalDescriptor, 163 | DvdCopyrightDescriptor, 164 | DvdDiskKeyDescriptor, 165 | DvdBCADescriptor, 166 | DvdManufacturerDescriptor, 167 | DvdMaxDescriptor 168 | } DVD_STRUCTURE_FORMAT, *PDVD_STRUCTURE_FORMAT; 169 | 170 | typedef struct DVD_READ_STRUCTURE { 171 | LARGE_INTEGER BlockByteOffset; 172 | DVD_STRUCTURE_FORMAT Format; 173 | DVD_SESSION_ID SessionId; 174 | UCHAR LayerNumber; 175 | } DVD_READ_STRUCTURE, *PDVD_READ_STRUCTURE; 176 | 177 | typedef struct DVD_COPYRIGHT_DESCRIPTOR { 178 | UCHAR CopyrightProtectionType; 179 | UCHAR RegionManagementInformation; 180 | USHORT Reserved; 181 | } DVD_COPYRIGHT_DESCRIPTOR, *PDVD_COPYRIGHT_DESCRIPTOR; 182 | 183 | typedef enum 184 | { 185 | DvdChallengeKey = 0x01, 186 | DvdBusKey1, 187 | DvdBusKey2, 188 | DvdTitleKey, 189 | DvdAsf, 190 | DvdSetRpcKey = 0x6, 191 | DvdGetRpcKey = 0x8, 192 | DvdDiskKey = 0x80, 193 | DvdInvalidateAGID = 0x3f 194 | } DVD_KEY_TYPE; 195 | 196 | typedef struct DVD_COPY_PROTECT_KEY 197 | { 198 | ULONG KeyLength; 199 | DVD_SESSION_ID SessionId; 200 | DVD_KEY_TYPE KeyType; 201 | ULONG KeyFlags; 202 | union 203 | { 204 | struct 205 | { 206 | ULONG FileHandle; 207 | ULONG Reserved; // used for NT alignment 208 | }; 209 | LARGE_INTEGER TitleOffset; 210 | } Parameters; 211 | UCHAR KeyData[0]; 212 | } DVD_COPY_PROTECT_KEY, *PDVD_COPY_PROTECT_KEY; 213 | 214 | typedef struct DVD_ASF 215 | { 216 | UCHAR Reserved0[3]; 217 | UCHAR SuccessFlag:1; 218 | UCHAR Reserved1:7; 219 | } DVD_ASF, * PDVD_ASF; 220 | 221 | typedef struct DVD_RPC_KEY 222 | { 223 | UCHAR UserResetsAvailable:3; 224 | UCHAR ManufacturerResetsAvailable:3; 225 | UCHAR TypeCode:2; 226 | UCHAR RegionMask; 227 | UCHAR RpcScheme; 228 | UCHAR Reserved2[1]; 229 | } DVD_RPC_KEY, * PDVD_RPC_KEY; 230 | 231 | typedef struct SCSI_PASS_THROUGH_DIRECT 232 | { 233 | USHORT Length; 234 | UCHAR ScsiStatus; 235 | UCHAR PathId; 236 | UCHAR TargetId; 237 | UCHAR Lun; 238 | UCHAR CdbLength; 239 | UCHAR SenseInfoLength; 240 | UCHAR DataIn; 241 | ULONG DataTransferLength; 242 | ULONG TimeOutValue; 243 | PVOID DataBuffer; 244 | ULONG SenseInfoOffset; 245 | UCHAR Cdb[16]; 246 | } SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; 247 | 248 | #endif /* defined( _WIN32 ) */ 249 | 250 | /***************************************************************************** 251 | * OS/2-ioctl-specific 252 | *****************************************************************************/ 253 | #if defined( __OS2__ ) 254 | 255 | #define CDROMDISK_EXECMD 0x7A 256 | 257 | #define EX_DIRECTION_IN 0x01 258 | #define EX_PLAYING_CHK 0x02 259 | 260 | #pragma pack(1) 261 | 262 | struct OS2_ExecSCSICmd 263 | { 264 | unsigned long id_code; // 'CD01' 265 | unsigned short data_length; // length of the Data Packet 266 | unsigned short cmd_length; // length of the Command Buffer 267 | unsigned short flags; // flags 268 | unsigned char command[16]; // Command Buffer for SCSI command 269 | 270 | } OS2_ExecSCSICmd; 271 | 272 | #pragma pack() 273 | 274 | #endif /* defined( __OS2__ ) */ 275 | 276 | #endif /* DVDCSS_IOCTL_H */ 277 | -------------------------------------------------------------------------------- /m4/attributes.m4: -------------------------------------------------------------------------------- 1 | dnl Macros to check the presence of generic (non-typed) symbols. 2 | dnl Copyright (c) 2006-2007 Diego Pettenò 3 | dnl Copyright (c) 2006-2007 xine project 4 | dnl 5 | dnl This program is free software; you can redistribute it and/or modify 6 | dnl it under the terms of the GNU General Public License as published by 7 | dnl the Free Software Foundation; either version 2, or (at your option) 8 | dnl any later version. 9 | dnl 10 | dnl This program is distributed in the hope that it will be useful, 11 | dnl but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | dnl GNU General Public License for more details. 14 | dnl 15 | dnl You should have received a copy of the GNU General Public License 16 | dnl along with this program; if not, write to the Free Software 17 | dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | dnl 02110-1301, USA. 19 | dnl 20 | dnl As a special exception, the copyright owners of the 21 | dnl macro gives unlimited permission to copy, distribute and modify the 22 | dnl configure scripts that are the output of Autoconf when processing the 23 | dnl Macro. You need not follow the terms of the GNU General Public 24 | dnl License when using or distributing such scripts, even though portions 25 | dnl of the text of the Macro appear in them. The GNU General Public 26 | dnl License (GPL) does govern all other use of the material that 27 | dnl constitutes the Autoconf Macro. 28 | dnl 29 | dnl This special exception to the GPL applies to versions of the 30 | dnl Autoconf Macro released by this project. When you make and 31 | dnl distribute a modified version of the Autoconf Macro, you may extend 32 | dnl this special exception to the GPL to apply to your modified version as 33 | dnl well. 34 | 35 | dnl Check if the flag is supported by compiler 36 | dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) 37 | 38 | AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [ 39 | AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]), 40 | [ac_save_CFLAGS="$CFLAGS" 41 | CFLAGS="$CFLAGS $1" 42 | AC_LINK_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])], 43 | [eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"], 44 | [eval "AS_TR_SH([cc_cv_cflags_$1])='no'"]) 45 | CFLAGS="$ac_save_CFLAGS" 46 | ]) 47 | 48 | AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], 49 | [$2], [$3]) 50 | ]) 51 | 52 | dnl Check if the flag is supported by compiler (cacheable) 53 | dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) 54 | 55 | AC_DEFUN([CC_CHECK_CFLAGS], [ 56 | AC_CACHE_CHECK([if $CC supports $1 flag], 57 | AS_TR_SH([cc_cv_cflags_$1]), 58 | CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! 59 | ) 60 | 61 | AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], 62 | [$2], [$3]) 63 | ]) 64 | 65 | dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found]) 66 | dnl Check for CFLAG and appends them to CFLAGS if supported 67 | AC_DEFUN([CC_CHECK_CFLAG_APPEND], [ 68 | AC_CACHE_CHECK([if $CC supports $1 flag], 69 | AS_TR_SH([cc_cv_cflags_$1]), 70 | CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! 71 | ) 72 | 73 | AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], 74 | [CFLAGS="$CFLAGS $1"; $2], [$3]) 75 | ]) 76 | 77 | dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not]) 78 | AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [ 79 | for flag in $1; do 80 | CC_CHECK_CFLAG_APPEND($flag, [$2], [$3]) 81 | done 82 | ]) 83 | 84 | dnl Check if the flag is supported by linker (cacheable) 85 | dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) 86 | 87 | AC_DEFUN([CC_CHECK_LDFLAGS], [ 88 | AC_CACHE_CHECK([if $CC supports $1 flag], 89 | AS_TR_SH([cc_cv_ldflags_$1]), 90 | [ac_save_LDFLAGS="$LDFLAGS" 91 | LDFLAGS="$LDFLAGS $1" 92 | AC_LINK_IFELSE([AC_LANG_SOURCE([int main(void) { return 1; }])], 93 | [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"], 94 | [eval "AS_TR_SH([cc_cv_ldflags_$1])="]) 95 | LDFLAGS="$ac_save_LDFLAGS" 96 | ]) 97 | 98 | AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes], 99 | [$2], [$3]) 100 | ]) 101 | 102 | dnl Check for a -Werror flag or equivalent. -Werror is the GCC 103 | dnl and ICC flag that tells the compiler to treat all the warnings 104 | dnl as fatal. We usually need this option to make sure that some 105 | dnl constructs (like attributes) are not simply ignored. 106 | dnl 107 | dnl Other compilers don't support -Werror per se, but they support 108 | dnl an equivalent flag: 109 | dnl - Sun Studio compiler supports -errwarn=%all 110 | AC_DEFUN([CC_CHECK_WERROR], [ 111 | AC_CACHE_CHECK( 112 | [for $CC way to treat warnings as errors], 113 | [cc_cv_werror], 114 | [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror], 115 | [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])]) 116 | ]) 117 | ]) 118 | 119 | AC_DEFUN([CC_CHECK_ATTRIBUTE], [ 120 | AC_REQUIRE([CC_CHECK_WERROR]) 121 | AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))], 122 | AS_TR_SH([cc_cv_attribute_$1]), 123 | [ac_save_CFLAGS="$CFLAGS" 124 | CFLAGS="$CFLAGS $cc_cv_werror" 125 | AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])], 126 | [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"], 127 | [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"]) 128 | CFLAGS="$ac_save_CFLAGS" 129 | ]) 130 | 131 | AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes], 132 | [AC_DEFINE( 133 | AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1, 134 | Define this if the compiler supports __attribute__((ifelse([$2], , [$1], [$2])))) 135 | $4], 136 | [$5]) 137 | ]) 138 | 139 | AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [ 140 | CC_CHECK_ATTRIBUTE( 141 | [constructor],, 142 | [extern void foo(); 143 | void __attribute__((constructor)) ctor() { foo(); }], 144 | [$1], [$2]) 145 | ]) 146 | 147 | AC_DEFUN([CC_ATTRIBUTE_DESTRUCTOR], [ 148 | CC_CHECK_ATTRIBUTE( 149 | [destructor],, 150 | [extern void foo(); 151 | void __attribute__((destructor)) dtor() { foo(); }], 152 | [$1], [$2]) 153 | ]) 154 | 155 | AC_DEFUN([CC_ATTRIBUTE_FORMAT], [ 156 | CC_CHECK_ATTRIBUTE( 157 | [format], [format(printf, n, n)], 158 | [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }], 159 | [$1], [$2]) 160 | ]) 161 | 162 | AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [ 163 | CC_CHECK_ATTRIBUTE( 164 | [format_arg], [format_arg(printf)], 165 | [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }], 166 | [$1], [$2]) 167 | ]) 168 | 169 | AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [ 170 | CC_CHECK_ATTRIBUTE( 171 | [visibility_$1], [visibility("$1")], 172 | [void __attribute__((visibility("$1"))) $1_function() { }], 173 | [$2], [$3]) 174 | ]) 175 | 176 | AC_DEFUN([CC_ATTRIBUTE_NONNULL], [ 177 | CC_CHECK_ATTRIBUTE( 178 | [nonnull], [nonnull()], 179 | [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }], 180 | [$1], [$2]) 181 | ]) 182 | 183 | AC_DEFUN([CC_ATTRIBUTE_UNUSED], [ 184 | CC_CHECK_ATTRIBUTE( 185 | [unused], , 186 | [void some_function(void *foo, __attribute__((unused)) void *bar);], 187 | [$1], [$2]) 188 | ]) 189 | 190 | AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [ 191 | CC_CHECK_ATTRIBUTE( 192 | [sentinel], , 193 | [void some_function(void *foo, ...) __attribute__((sentinel));], 194 | [$1], [$2]) 195 | ]) 196 | 197 | AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [ 198 | CC_CHECK_ATTRIBUTE( 199 | [deprecated], , 200 | [void some_function(void *foo, ...) __attribute__((deprecated));], 201 | [$1], [$2]) 202 | ]) 203 | 204 | AC_DEFUN([CC_ATTRIBUTE_ALIAS], [ 205 | CC_CHECK_ATTRIBUTE( 206 | [alias], [weak, alias], 207 | [void other_function(void *foo) { } 208 | void some_function(void *foo) __attribute__((weak, alias("other_function")));], 209 | [$1], [$2]) 210 | ]) 211 | 212 | AC_DEFUN([CC_ATTRIBUTE_MALLOC], [ 213 | CC_CHECK_ATTRIBUTE( 214 | [malloc], , 215 | [void * __attribute__((malloc)) my_alloc(int n);], 216 | [$1], [$2]) 217 | ]) 218 | 219 | AC_DEFUN([CC_ATTRIBUTE_PACKED], [ 220 | CC_CHECK_ATTRIBUTE( 221 | [packed], , 222 | [struct astructure { char a; int b; long c; void *d; } __attribute__((packed)); 223 | char assert@<:@(sizeof(struct astructure) == (sizeof(char)+sizeof(int)+sizeof(long)+sizeof(void*)))-1@:>@;], 224 | [$1], [$2]) 225 | ]) 226 | 227 | AC_DEFUN([CC_ATTRIBUTE_CONST], [ 228 | CC_CHECK_ATTRIBUTE( 229 | [const], , 230 | [int __attribute__((const)) twopow(int n) { return 1 << n; } ], 231 | [$1], [$2]) 232 | ]) 233 | 234 | AC_DEFUN([CC_FLAG_VISIBILITY], [ 235 | AC_REQUIRE([CC_CHECK_WERROR]) 236 | AC_CACHE_CHECK([if $CC supports -fvisibility=hidden], 237 | [cc_cv_flag_visibility], 238 | [cc_flag_visibility_save_CFLAGS="$CFLAGS" 239 | CFLAGS="$CFLAGS $cc_cv_werror" 240 | CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden], 241 | cc_cv_flag_visibility='yes', 242 | cc_cv_flag_visibility='no') 243 | CFLAGS="$cc_flag_visibility_save_CFLAGS"]) 244 | 245 | AS_IF([test "x$cc_cv_flag_visibility" = "xyes"], 246 | [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1, 247 | [Define this if the compiler supports the -fvisibility flag]) 248 | $1], 249 | [$2]) 250 | ]) 251 | 252 | AC_DEFUN([CC_FUNC_EXPECT], [ 253 | AC_REQUIRE([CC_CHECK_WERROR]) 254 | AC_CACHE_CHECK([if compiler has __builtin_expect function], 255 | [cc_cv_func_expect], 256 | [ac_save_CFLAGS="$CFLAGS" 257 | CFLAGS="$CFLAGS $cc_cv_werror" 258 | AC_COMPILE_IFELSE( 259 | [int some_function() { 260 | int a = 3; 261 | return (int)__builtin_expect(a, 3); 262 | }], 263 | [cc_cv_func_expect=yes], 264 | [cc_cv_func_expect=no]) 265 | CFLAGS="$ac_save_CFLAGS" 266 | ]) 267 | 268 | AS_IF([test "x$cc_cv_func_expect" = "xyes"], 269 | [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1, 270 | [Define this if the compiler supports __builtin_expect() function]) 271 | $1], 272 | [$2]) 273 | ]) 274 | 275 | AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ 276 | AC_REQUIRE([CC_CHECK_WERROR]) 277 | AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported], 278 | [cc_cv_attribute_aligned], 279 | [ac_save_CFLAGS="$CFLAGS" 280 | CFLAGS="$CFLAGS $cc_cv_werror" 281 | for cc_attribute_align_try in 64 32 16 8 4 2; do 282 | AC_COMPILE_IFELSE([ 283 | int main(void) { 284 | static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0; 285 | return c; 286 | }], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) 287 | done 288 | CFLAGS="$ac_save_CFLAGS" 289 | ]) 290 | 291 | if test "x$cc_cv_attribute_aligned" != "x"; then 292 | AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], 293 | [Define the highest alignment supported]) 294 | fi 295 | ]) 296 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /src/csstables.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * csstables.h: CSS Tables for DVD unscrambling 3 | ***************************************************************************** 4 | * Copyright (C) 1999-2001 VideoLAN 5 | * 6 | * Author: Stéphane Borel 7 | * 8 | * based on: 9 | * - css-auth by Derek Fawcus 10 | * - DVD CSS ioctls example program by Andrew T. Veliath 11 | * - The Divide and conquer attack by Frank A. Stevenson 12 | * - DeCSSPlus by Ethan Hawke 13 | * - DecVOB 14 | * see http://www.lemuria.org/DeCSS/ by Tom Vogt for more information. 15 | * 16 | * libdvdcss is free software; you can redistribute it and/or modify 17 | * it under the terms of the GNU General Public License as published by 18 | * the Free Software Foundation; either version 2 of the License, or 19 | * (at your option) any later version. 20 | * 21 | * libdvdcss is distributed in the hope that it will be useful, 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | * GNU General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU General Public License along 27 | * with libdvdcss; if not, write to the Free Software Foundation, Inc., 28 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 29 | *****************************************************************************/ 30 | 31 | #ifndef DVDCSS_CSSTABLES_H 32 | #define DVDCSS_CSSTABLES_H 33 | 34 | #include 35 | 36 | static const uint8_t p_css_tab1[ 256 ] = 37 | { 38 | 0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76, 39 | 0x3e, 0x7e, 0x36, 0x2b, 0x6e, 0x2e, 0x66, 0x7b, 40 | 0xd3, 0x93, 0xdb, 0x06, 0x43, 0x03, 0x4b, 0x96, 41 | 0xde, 0x9e, 0xd6, 0x0b, 0x4e, 0x0e, 0x46, 0x9b, 42 | 0x57, 0x17, 0x5f, 0x82, 0xc7, 0x87, 0xcf, 0x12, 43 | 0x5a, 0x1a, 0x52, 0x8f, 0xca, 0x8a, 0xc2, 0x1f, 44 | 0xd9, 0x99, 0xd1, 0x00, 0x49, 0x09, 0x41, 0x90, 45 | 0xd8, 0x98, 0xd0, 0x01, 0x48, 0x08, 0x40, 0x91, 46 | 0x3d, 0x7d, 0x35, 0x24, 0x6d, 0x2d, 0x65, 0x74, 47 | 0x3c, 0x7c, 0x34, 0x25, 0x6c, 0x2c, 0x64, 0x75, 48 | 0xdd, 0x9d, 0xd5, 0x04, 0x4d, 0x0d, 0x45, 0x94, 49 | 0xdc, 0x9c, 0xd4, 0x05, 0x4c, 0x0c, 0x44, 0x95, 50 | 0x59, 0x19, 0x51, 0x80, 0xc9, 0x89, 0xc1, 0x10, 51 | 0x58, 0x18, 0x50, 0x81, 0xc8, 0x88, 0xc0, 0x11, 52 | 0xd7, 0x97, 0xdf, 0x02, 0x47, 0x07, 0x4f, 0x92, 53 | 0xda, 0x9a, 0xd2, 0x0f, 0x4a, 0x0a, 0x42, 0x9f, 54 | 0x53, 0x13, 0x5b, 0x86, 0xc3, 0x83, 0xcb, 0x16, 55 | 0x5e, 0x1e, 0x56, 0x8b, 0xce, 0x8e, 0xc6, 0x1b, 56 | 0xb3, 0xf3, 0xbb, 0xa6, 0xe3, 0xa3, 0xeb, 0xf6, 57 | 0xbe, 0xfe, 0xb6, 0xab, 0xee, 0xae, 0xe6, 0xfb, 58 | 0x37, 0x77, 0x3f, 0x22, 0x67, 0x27, 0x6f, 0x72, 59 | 0x3a, 0x7a, 0x32, 0x2f, 0x6a, 0x2a, 0x62, 0x7f, 60 | 0xb9, 0xf9, 0xb1, 0xa0, 0xe9, 0xa9, 0xe1, 0xf0, 61 | 0xb8, 0xf8, 0xb0, 0xa1, 0xe8, 0xa8, 0xe0, 0xf1, 62 | 0x5d, 0x1d, 0x55, 0x84, 0xcd, 0x8d, 0xc5, 0x14, 63 | 0x5c, 0x1c, 0x54, 0x85, 0xcc, 0x8c, 0xc4, 0x15, 64 | 0xbd, 0xfd, 0xb5, 0xa4, 0xed, 0xad, 0xe5, 0xf4, 65 | 0xbc, 0xfc, 0xb4, 0xa5, 0xec, 0xac, 0xe4, 0xf5, 66 | 0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70, 67 | 0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71, 68 | 0xb7, 0xf7, 0xbf, 0xa2, 0xe7, 0xa7, 0xef, 0xf2, 69 | 0xba, 0xfa, 0xb2, 0xaf, 0xea, 0xaa, 0xe2, 0xff 70 | }; 71 | 72 | static const uint8_t p_css_tab2[ 256 ] = 73 | { 74 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 75 | 0x09, 0x08, 0x0b, 0x0a, 0x0d, 0x0c, 0x0f, 0x0e, 76 | 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 77 | 0x1b, 0x1a, 0x19, 0x18, 0x1f, 0x1e, 0x1d, 0x1c, 78 | 0x24, 0x25, 0x26, 0x27, 0x20, 0x21, 0x22, 0x23, 79 | 0x2d, 0x2c, 0x2f, 0x2e, 0x29, 0x28, 0x2b, 0x2a, 80 | 0x36, 0x37, 0x34, 0x35, 0x32, 0x33, 0x30, 0x31, 81 | 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 82 | 0x49, 0x48, 0x4b, 0x4a, 0x4d, 0x4c, 0x4f, 0x4e, 83 | 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 84 | 0x5b, 0x5a, 0x59, 0x58, 0x5f, 0x5e, 0x5d, 0x5c, 85 | 0x52, 0x53, 0x50, 0x51, 0x56, 0x57, 0x54, 0x55, 86 | 0x6d, 0x6c, 0x6f, 0x6e, 0x69, 0x68, 0x6b, 0x6a, 87 | 0x64, 0x65, 0x66, 0x67, 0x60, 0x61, 0x62, 0x63, 88 | 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 89 | 0x76, 0x77, 0x74, 0x75, 0x72, 0x73, 0x70, 0x71, 90 | 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 91 | 0x9b, 0x9a, 0x99, 0x98, 0x9f, 0x9e, 0x9d, 0x9c, 92 | 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 93 | 0x89, 0x88, 0x8b, 0x8a, 0x8d, 0x8c, 0x8f, 0x8e, 94 | 0xb6, 0xb7, 0xb4, 0xb5, 0xb2, 0xb3, 0xb0, 0xb1, 95 | 0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8, 96 | 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3, 97 | 0xad, 0xac, 0xaf, 0xae, 0xa9, 0xa8, 0xab, 0xaa, 98 | 0xdb, 0xda, 0xd9, 0xd8, 0xdf, 0xde, 0xdd, 0xdc, 99 | 0xd2, 0xd3, 0xd0, 0xd1, 0xd6, 0xd7, 0xd4, 0xd5, 100 | 0xc9, 0xc8, 0xcb, 0xca, 0xcd, 0xcc, 0xcf, 0xce, 101 | 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 102 | 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 103 | 0xf6, 0xf7, 0xf4, 0xf5, 0xf2, 0xf3, 0xf0, 0xf1, 104 | 0xed, 0xec, 0xef, 0xee, 0xe9, 0xe8, 0xeb, 0xea, 105 | 0xe4, 0xe5, 0xe6, 0xe7, 0xe0, 0xe1, 0xe2, 0xe3 106 | }; 107 | 108 | static const uint8_t p_css_tab3[ 512 ] = 109 | { 110 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 111 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 112 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 113 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 114 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 115 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 116 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 117 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 118 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 119 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 120 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 121 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 122 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 123 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 124 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 125 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 126 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 127 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 128 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 129 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 130 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 131 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 132 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 133 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 134 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 135 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 136 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 137 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 138 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 139 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 140 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 141 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 142 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 143 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 144 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 145 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 146 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 147 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 148 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 149 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 150 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 151 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 152 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 153 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 154 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 155 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 156 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 157 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 158 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 159 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 160 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 161 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 162 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 163 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 164 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 165 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 166 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 167 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 168 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 169 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 170 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 171 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 172 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 173 | 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff 174 | }; 175 | 176 | static const uint8_t p_css_tab4[ 256 ] = 177 | { 178 | 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 179 | 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 180 | 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 181 | 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 182 | 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 183 | 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 184 | 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 185 | 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 186 | 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 187 | 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 188 | 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 189 | 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 190 | 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 191 | 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 192 | 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 193 | 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 194 | 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 195 | 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 196 | 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 197 | 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 198 | 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 199 | 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 200 | 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 201 | 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 202 | 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 203 | 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 204 | 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 205 | 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 206 | 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 207 | 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 208 | 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 209 | 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff 210 | }; 211 | 212 | static const uint8_t p_css_tab5[ 256 ] = 213 | { 214 | 0xff, 0x7f, 0xbf, 0x3f, 0xdf, 0x5f, 0x9f, 0x1f, 215 | 0xef, 0x6f, 0xaf, 0x2f, 0xcf, 0x4f, 0x8f, 0x0f, 216 | 0xf7, 0x77, 0xb7, 0x37, 0xd7, 0x57, 0x97, 0x17, 217 | 0xe7, 0x67, 0xa7, 0x27, 0xc7, 0x47, 0x87, 0x07, 218 | 0xfb, 0x7b, 0xbb, 0x3b, 0xdb, 0x5b, 0x9b, 0x1b, 219 | 0xeb, 0x6b, 0xab, 0x2b, 0xcb, 0x4b, 0x8b, 0x0b, 220 | 0xf3, 0x73, 0xb3, 0x33, 0xd3, 0x53, 0x93, 0x13, 221 | 0xe3, 0x63, 0xa3, 0x23, 0xc3, 0x43, 0x83, 0x03, 222 | 0xfd, 0x7d, 0xbd, 0x3d, 0xdd, 0x5d, 0x9d, 0x1d, 223 | 0xed, 0x6d, 0xad, 0x2d, 0xcd, 0x4d, 0x8d, 0x0d, 224 | 0xf5, 0x75, 0xb5, 0x35, 0xd5, 0x55, 0x95, 0x15, 225 | 0xe5, 0x65, 0xa5, 0x25, 0xc5, 0x45, 0x85, 0x05, 226 | 0xf9, 0x79, 0xb9, 0x39, 0xd9, 0x59, 0x99, 0x19, 227 | 0xe9, 0x69, 0xa9, 0x29, 0xc9, 0x49, 0x89, 0x09, 228 | 0xf1, 0x71, 0xb1, 0x31, 0xd1, 0x51, 0x91, 0x11, 229 | 0xe1, 0x61, 0xa1, 0x21, 0xc1, 0x41, 0x81, 0x01, 230 | 0xfe, 0x7e, 0xbe, 0x3e, 0xde, 0x5e, 0x9e, 0x1e, 231 | 0xee, 0x6e, 0xae, 0x2e, 0xce, 0x4e, 0x8e, 0x0e, 232 | 0xf6, 0x76, 0xb6, 0x36, 0xd6, 0x56, 0x96, 0x16, 233 | 0xe6, 0x66, 0xa6, 0x26, 0xc6, 0x46, 0x86, 0x06, 234 | 0xfa, 0x7a, 0xba, 0x3a, 0xda, 0x5a, 0x9a, 0x1a, 235 | 0xea, 0x6a, 0xaa, 0x2a, 0xca, 0x4a, 0x8a, 0x0a, 236 | 0xf2, 0x72, 0xb2, 0x32, 0xd2, 0x52, 0x92, 0x12, 237 | 0xe2, 0x62, 0xa2, 0x22, 0xc2, 0x42, 0x82, 0x02, 238 | 0xfc, 0x7c, 0xbc, 0x3c, 0xdc, 0x5c, 0x9c, 0x1c, 239 | 0xec, 0x6c, 0xac, 0x2c, 0xcc, 0x4c, 0x8c, 0x0c, 240 | 0xf4, 0x74, 0xb4, 0x34, 0xd4, 0x54, 0x94, 0x14, 241 | 0xe4, 0x64, 0xa4, 0x24, 0xc4, 0x44, 0x84, 0x04, 242 | 0xf8, 0x78, 0xb8, 0x38, 0xd8, 0x58, 0x98, 0x18, 243 | 0xe8, 0x68, 0xa8, 0x28, 0xc8, 0x48, 0x88, 0x08, 244 | 0xf0, 0x70, 0xb0, 0x30, 0xd0, 0x50, 0x90, 0x10, 245 | 0xe0, 0x60, 0xa0, 0x20, 0xc0, 0x40, 0x80, 0x00 246 | }; 247 | 248 | static const uint8_t p_crypt_tab0[ 256 ] = 249 | { 250 | 0xB7, 0xF4, 0x82, 0x57, 0xDA, 0x4D, 0xDB, 0xE2, 251 | 0x2F, 0x52, 0x1A, 0xA8, 0x68, 0x5A, 0x8A, 0xFF, 252 | 0xFB, 0x0E, 0x6D, 0x35, 0xF7, 0x5C, 0x76, 0x12, 253 | 0xCE, 0x25, 0x79, 0x29, 0x39, 0x62, 0x08, 0x24, 254 | 0xA5, 0x85, 0x7B, 0x56, 0x01, 0x23, 0x68, 0xCF, 255 | 0x0A, 0xE2, 0x5A, 0xED, 0x3D, 0x59, 0xB0, 0xA9, 256 | 0xB0, 0x2C, 0xF2, 0xB8, 0xEF, 0x32, 0xA9, 0x40, 257 | 0x80, 0x71, 0xAF, 0x1E, 0xDE, 0x8F, 0x58, 0x88, 258 | 0xB8, 0x3A, 0xD0, 0xFC, 0xC4, 0x1E, 0xB5, 0xA0, 259 | 0xBB, 0x3B, 0x0F, 0x01, 0x7E, 0x1F, 0x9F, 0xD9, 260 | 0xAA, 0xB8, 0x3D, 0x9D, 0x74, 0x1E, 0x25, 0xDB, 261 | 0x37, 0x56, 0x8F, 0x16, 0xBA, 0x49, 0x2B, 0xAC, 262 | 0xD0, 0xBD, 0x95, 0x20, 0xBE, 0x7A, 0x28, 0xD0, 263 | 0x51, 0x64, 0x63, 0x1C, 0x7F, 0x66, 0x10, 0xBB, 264 | 0xC4, 0x56, 0x1A, 0x04, 0x6E, 0x0A, 0xEC, 0x9C, 265 | 0xD6, 0xE8, 0x9A, 0x7A, 0xCF, 0x8C, 0xDB, 0xB1, 266 | 0xEF, 0x71, 0xDE, 0x31, 0xFF, 0x54, 0x3E, 0x5E, 267 | 0x07, 0x69, 0x96, 0xB0, 0xCF, 0xDD, 0x9E, 0x47, 268 | 0xC7, 0x96, 0x8F, 0xE4, 0x2B, 0x59, 0xC6, 0xEE, 269 | 0xB9, 0x86, 0x9A, 0x64, 0x84, 0x72, 0xE2, 0x5B, 270 | 0xA2, 0x96, 0x58, 0x99, 0x50, 0x03, 0xF5, 0x38, 271 | 0x4D, 0x02, 0x7D, 0xE7, 0x7D, 0x75, 0xA7, 0xB8, 272 | 0x67, 0x87, 0x84, 0x3F, 0x1D, 0x11, 0xE5, 0xFC, 273 | 0x1E, 0xD3, 0x83, 0x16, 0xA5, 0x29, 0xF6, 0xC7, 274 | 0x15, 0x61, 0x29, 0x1A, 0x43, 0x4F, 0x9B, 0xAF, 275 | 0xC5, 0x87, 0x34, 0x6C, 0x0F, 0x3B, 0xA8, 0x1D, 276 | 0x45, 0x58, 0x25, 0xDC, 0xA8, 0xA3, 0x3B, 0xD1, 277 | 0x79, 0x1B, 0x48, 0xF2, 0xE9, 0x93, 0x1F, 0xFC, 278 | 0xDB, 0x2A, 0x90, 0xA9, 0x8A, 0x3D, 0x39, 0x18, 279 | 0xA3, 0x8E, 0x58, 0x6C, 0xE0, 0x12, 0xBB, 0x25, 280 | 0xCD, 0x71, 0x22, 0xA2, 0x64, 0xC6, 0xE7, 0xFB, 281 | 0xAD, 0x94, 0x77, 0x04, 0x9A, 0x39, 0xCF, 0x7C 282 | }; 283 | 284 | static const uint8_t p_crypt_tab1[ 256 ] = 285 | { 286 | 0x8C, 0x47, 0xB0, 0xE1, 0xEB, 0xFC, 0xEB, 0x56, 287 | 0x10, 0xE5, 0x2C, 0x1A, 0x5D, 0xEF, 0xBE, 0x4F, 288 | 0x08, 0x75, 0x97, 0x4B, 0x0E, 0x25, 0x8E, 0x6E, 289 | 0x39, 0x5A, 0x87, 0x53, 0xC4, 0x1F, 0xF4, 0x5C, 290 | 0x4E, 0xE6, 0x99, 0x30, 0xE0, 0x42, 0x88, 0xAB, 291 | 0xE5, 0x85, 0xBC, 0x8F, 0xD8, 0x3C, 0x54, 0xC9, 292 | 0x53, 0x47, 0x18, 0xD6, 0x06, 0x5B, 0x41, 0x2C, 293 | 0x67, 0x1E, 0x41, 0x74, 0x33, 0xE2, 0xB4, 0xE0, 294 | 0x23, 0x29, 0x42, 0xEA, 0x55, 0x0F, 0x25, 0xB4, 295 | 0x24, 0x2C, 0x99, 0x13, 0xEB, 0x0A, 0x0B, 0xC9, 296 | 0xF9, 0x63, 0x67, 0x43, 0x2D, 0xC7, 0x7D, 0x07, 297 | 0x60, 0x89, 0xD1, 0xCC, 0xE7, 0x94, 0x77, 0x74, 298 | 0x9B, 0x7E, 0xD7, 0xE6, 0xFF, 0xBB, 0x68, 0x14, 299 | 0x1E, 0xA3, 0x25, 0xDE, 0x3A, 0xA3, 0x54, 0x7B, 300 | 0x87, 0x9D, 0x50, 0xCA, 0x27, 0xC3, 0xA4, 0x50, 301 | 0x91, 0x27, 0xD4, 0xB0, 0x82, 0x41, 0x97, 0x79, 302 | 0x94, 0x82, 0xAC, 0xC7, 0x8E, 0xA5, 0x4E, 0xAA, 303 | 0x78, 0x9E, 0xE0, 0x42, 0xBA, 0x28, 0xEA, 0xB7, 304 | 0x74, 0xAD, 0x35, 0xDA, 0x92, 0x60, 0x7E, 0xD2, 305 | 0x0E, 0xB9, 0x24, 0x5E, 0x39, 0x4F, 0x5E, 0x63, 306 | 0x09, 0xB5, 0xFA, 0xBF, 0xF1, 0x22, 0x55, 0x1C, 307 | 0xE2, 0x25, 0xDB, 0xC5, 0xD8, 0x50, 0x03, 0x98, 308 | 0xC4, 0xAC, 0x2E, 0x11, 0xB4, 0x38, 0x4D, 0xD0, 309 | 0xB9, 0xFC, 0x2D, 0x3C, 0x08, 0x04, 0x5A, 0xEF, 310 | 0xCE, 0x32, 0xFB, 0x4C, 0x92, 0x1E, 0x4B, 0xFB, 311 | 0x1A, 0xD0, 0xE2, 0x3E, 0xDA, 0x6E, 0x7C, 0x4D, 312 | 0x56, 0xC3, 0x3F, 0x42, 0xB1, 0x3A, 0x23, 0x4D, 313 | 0x6E, 0x84, 0x56, 0x68, 0xF4, 0x0E, 0x03, 0x64, 314 | 0xD0, 0xA9, 0x92, 0x2F, 0x8B, 0xBC, 0x39, 0x9C, 315 | 0xAC, 0x09, 0x5E, 0xEE, 0xE5, 0x97, 0xBF, 0xA5, 316 | 0xCE, 0xFA, 0x28, 0x2C, 0x6D, 0x4F, 0xEF, 0x77, 317 | 0xAA, 0x1B, 0x79, 0x8E, 0x97, 0xB4, 0xC3, 0xF4 318 | }; 319 | 320 | static const uint8_t p_crypt_tab2[ 256 ] = 321 | { 322 | 0xB7, 0x75, 0x81, 0xD5, 0xDC, 0xCA, 0xDE, 0x66, 323 | 0x23, 0xDF, 0x15, 0x26, 0x62, 0xD1, 0x83, 0x77, 324 | 0xE3, 0x97, 0x76, 0xAF, 0xE9, 0xC3, 0x6B, 0x8E, 325 | 0xDA, 0xB0, 0x6E, 0xBF, 0x2B, 0xF1, 0x19, 0xB4, 326 | 0x95, 0x34, 0x48, 0xE4, 0x37, 0x94, 0x5D, 0x7B, 327 | 0x36, 0x5F, 0x65, 0x53, 0x07, 0xE2, 0x89, 0x11, 328 | 0x98, 0x85, 0xD9, 0x12, 0xC1, 0x9D, 0x84, 0xEC, 329 | 0xA4, 0xD4, 0x88, 0xB8, 0xFC, 0x2C, 0x79, 0x28, 330 | 0xD8, 0xDB, 0xB3, 0x1E, 0xA2, 0xF9, 0xD0, 0x44, 331 | 0xD7, 0xD6, 0x60, 0xEF, 0x14, 0xF4, 0xF6, 0x31, 332 | 0xD2, 0x41, 0x46, 0x67, 0x0A, 0xE1, 0x58, 0x27, 333 | 0x43, 0xA3, 0xF8, 0xE0, 0xC8, 0xBA, 0x5A, 0x5C, 334 | 0x80, 0x6C, 0xC6, 0xF2, 0xE8, 0xAD, 0x7D, 0x04, 335 | 0x0D, 0xB9, 0x3C, 0xC2, 0x25, 0xBD, 0x49, 0x63, 336 | 0x8C, 0x9F, 0x51, 0xCE, 0x20, 0xC5, 0xA1, 0x50, 337 | 0x92, 0x2D, 0xDD, 0xBC, 0x8D, 0x4F, 0x9A, 0x71, 338 | 0x2F, 0x30, 0x1D, 0x73, 0x39, 0x13, 0xFB, 0x1A, 339 | 0xCB, 0x24, 0x59, 0xFE, 0x05, 0x96, 0x57, 0x0F, 340 | 0x1F, 0xCF, 0x54, 0xBE, 0xF5, 0x06, 0x1B, 0xB2, 341 | 0x6D, 0xD3, 0x4D, 0x32, 0x56, 0x21, 0x33, 0x0B, 342 | 0x52, 0xE7, 0xAB, 0xEB, 0xA6, 0x74, 0x00, 0x4C, 343 | 0xB1, 0x7F, 0x82, 0x99, 0x87, 0x0E, 0x5E, 0xC0, 344 | 0x8F, 0xEE, 0x6F, 0x55, 0xF3, 0x7E, 0x08, 0x90, 345 | 0xFA, 0xB6, 0x64, 0x70, 0x47, 0x4A, 0x17, 0xA7, 346 | 0xB5, 0x40, 0x8A, 0x38, 0xE5, 0x68, 0x3E, 0x8B, 347 | 0x69, 0xAA, 0x9B, 0x42, 0xA5, 0x10, 0x01, 0x35, 348 | 0xFD, 0x61, 0x9E, 0xE6, 0x16, 0x9C, 0x86, 0xED, 349 | 0xCD, 0x2E, 0xFF, 0xC4, 0x5B, 0xA0, 0xAE, 0xCC, 350 | 0x4B, 0x3B, 0x03, 0xBB, 0x1C, 0x2A, 0xAC, 0x0C, 351 | 0x3F, 0x93, 0xC7, 0x72, 0x7A, 0x09, 0x22, 0x3D, 352 | 0x45, 0x78, 0xA9, 0xA8, 0xEA, 0xC9, 0x6A, 0xF7, 353 | 0x29, 0x91, 0xF0, 0x02, 0x18, 0x3A, 0x4E, 0x7C 354 | }; 355 | 356 | static const uint8_t p_crypt_tab3[ 288 ] = 357 | { 358 | 0x73, 0x51, 0x95, 0xE1, 0x12, 0xE4, 0xC0, 0x58, 359 | 0xEE, 0xF2, 0x08, 0x1B, 0xA9, 0xFA, 0x98, 0x4C, 360 | 0xA7, 0x33, 0xE2, 0x1B, 0xA7, 0x6D, 0xF5, 0x30, 361 | 0x97, 0x1D, 0xF3, 0x02, 0x60, 0x5A, 0x82, 0x0F, 362 | 0x91, 0xD0, 0x9C, 0x10, 0x39, 0x7A, 0x83, 0x85, 363 | 0x3B, 0xB2, 0xB8, 0xAE, 0x0C, 0x09, 0x52, 0xEA, 364 | 0x1C, 0xE1, 0x8D, 0x66, 0x4F, 0xF3, 0xDA, 0x92, 365 | 0x29, 0xB9, 0xD5, 0xC5, 0x77, 0x47, 0x22, 0x53, 366 | 0x14, 0xF7, 0xAF, 0x22, 0x64, 0xDF, 0xC6, 0x72, 367 | 0x12, 0xF3, 0x75, 0xDA, 0xD7, 0xD7, 0xE5, 0x02, 368 | 0x9E, 0xED, 0xDA, 0xDB, 0x4C, 0x47, 0xCE, 0x91, 369 | 0x06, 0x06, 0x6D, 0x55, 0x8B, 0x19, 0xC9, 0xEF, 370 | 0x8C, 0x80, 0x1A, 0x0E, 0xEE, 0x4B, 0xAB, 0xF2, 371 | 0x08, 0x5C, 0xE9, 0x37, 0x26, 0x5E, 0x9A, 0x90, 372 | 0x00, 0xF3, 0x0D, 0xB2, 0xA6, 0xA3, 0xF7, 0x26, 373 | 0x17, 0x48, 0x88, 0xC9, 0x0E, 0x2C, 0xC9, 0x02, 374 | 0xE7, 0x18, 0x05, 0x4B, 0xF3, 0x39, 0xE1, 0x20, 375 | 0x02, 0x0D, 0x40, 0xC7, 0xCA, 0xB9, 0x48, 0x30, 376 | 0x57, 0x67, 0xCC, 0x06, 0xBF, 0xAC, 0x81, 0x08, 377 | 0x24, 0x7A, 0xD4, 0x8B, 0x19, 0x8E, 0xAC, 0xB4, 378 | 0x5A, 0x0F, 0x73, 0x13, 0xAC, 0x9E, 0xDA, 0xB6, 379 | 0xB8, 0x96, 0x5B, 0x60, 0x88, 0xE1, 0x81, 0x3F, 380 | 0x07, 0x86, 0x37, 0x2D, 0x79, 0x14, 0x52, 0xEA, 381 | 0x73, 0xDF, 0x3D, 0x09, 0xC8, 0x25, 0x48, 0xD8, 382 | 0x75, 0x60, 0x9A, 0x08, 0x27, 0x4A, 0x2C, 0xB9, 383 | 0xA8, 0x8B, 0x8A, 0x73, 0x62, 0x37, 0x16, 0x02, 384 | 0xBD, 0xC1, 0x0E, 0x56, 0x54, 0x3E, 0x14, 0x5F, 385 | 0x8C, 0x8F, 0x6E, 0x75, 0x1C, 0x07, 0x39, 0x7B, 386 | 0x4B, 0xDB, 0xD3, 0x4B, 0x1E, 0xC8, 0x7E, 0xFE, 387 | 0x3E, 0x72, 0x16, 0x83, 0x7D, 0xEE, 0xF5, 0xCA, 388 | 0xC5, 0x18, 0xF9, 0xD8, 0x68, 0xAB, 0x38, 0x85, 389 | 0xA8, 0xF0, 0xA1, 0x73, 0x9F, 0x5D, 0x19, 0x0B, 390 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 391 | 0x33, 0x72, 0x39, 0x25, 0x67, 0x26, 0x6D, 0x71, 392 | 0x36, 0x77, 0x3C, 0x20, 0x62, 0x23, 0x68, 0x74, 393 | 0xC3, 0x82, 0xC9, 0x15, 0x57, 0x16, 0x5D, 0x81 394 | }; 395 | 396 | #endif /* DVDCSS_CSSTABLES_H */ 397 | -------------------------------------------------------------------------------- /src/libdvdcss.c: -------------------------------------------------------------------------------- 1 | /* libdvdcss.c: DVD reading library. 2 | * 3 | * Authors: Stéphane Borel 4 | * Sam Hocevar 5 | * Håkan Hjort 6 | * 7 | * Copyright (C) 1998-2008 VideoLAN 8 | * 9 | * libdvdcss is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * libdvdcss is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along 20 | * with libdvdcss; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 | */ 23 | 24 | /** 25 | * \mainpage libdvdcss developer documentation 26 | * 27 | * \section intro Introduction 28 | * 29 | * \e libdvdcss is a simple library designed for accessing DVDs like a block 30 | * device without having to bother about the decryption. The important features 31 | * are: 32 | * \li portability: Currently supported platforms are GNU/Linux, FreeBSD, 33 | * NetBSD, OpenBSD, Haiku, Mac OS X, Solaris, QNX, OS/2, and Windows 34 | * 2000 or later. 35 | * \li adaptability: Unlike most similar projects, libdvdcss does not require 36 | * the region of your drive to be set and will try its best to read from 37 | * the disc even in the case of a region mismatch. 38 | * \li simplicity: A DVD player can be built around the \e libdvdcss API using 39 | * no more than 4 or 5 library calls. 40 | * 41 | * \e libdvdcss is free software, released under the GNU General Public License. 42 | * This ensures that \e libdvdcss remains free and used only with free 43 | * software. 44 | * 45 | * \section api The libdvdcss API 46 | * 47 | * The complete \e libdvdcss programming interface is documented in the 48 | * dvdcss.h file. 49 | * 50 | * \section env Environment variables 51 | * 52 | * Some environment variables can be used to change the behavior of 53 | * \e libdvdcss without having to modify the program which uses it. These 54 | * variables are: 55 | * 56 | * \li \b DVDCSS_VERBOSE: Sets the verbosity level. 57 | * - \c 0 outputs no messages at all. 58 | * - \c 1 outputs error messages to stderr. 59 | * - \c 2 outputs error messages and debug messages to stderr. 60 | * 61 | * \li \b DVDCSS_METHOD: Sets the authentication and decryption method 62 | * that \e libdvdcss will use to read scrambled discs. Can be one 63 | * of \c title, \c key or \c disc. 64 | * - \c key is the default method. \e libdvdcss will use a set of 65 | * calculated player keys to try and get the disc key. This can fail 66 | * if the drive does not recognize any of the player keys. 67 | * - \c disc is a fallback method when \c key has failed. Instead of 68 | * using player keys, \e libdvdcss will crack the disc key using 69 | * a brute force algorithm. This process is CPU intensive and requires 70 | * 64 MB of memory to store temporary data. 71 | * - \c title is the fallback when all other methods have failed. It does 72 | * not rely on a key exchange with the DVD drive, but rather uses a 73 | * crypto attack to guess the title key. In rare cases this may fail 74 | * because there is not enough encrypted data on the disc to perform 75 | * a statistical attack, but on the other hand it is the only way to 76 | * decrypt a DVD stored on a hard disc, or a DVD with the wrong region 77 | * on an RPC2 drive. 78 | * 79 | * \li \b DVDCSS_RAW_DEVICE: Specify the raw device to use. Exact usage will 80 | * depend on your operating system, the Linux utility to set up raw devices 81 | * is \c raw(8) for instance. Please note that on most operating systems, 82 | * using a raw device requires highly aligned buffers: Linux requires a 83 | * 2048 bytes alignment (which is the size of a DVD sector). 84 | * 85 | * \li \b DVDCSS_CACHE: Specify a directory in which to cache title key 86 | * values. This will speed up descrambling of DVDs which are in the 87 | * cache. The DVDCSS_CACHE directory is created if it does not exist, 88 | * and a subdirectory is created named after the DVD's title or 89 | * manufacturing date. If DVDCSS_CACHE is not set or is empty, \e libdvdcss 90 | * will use the default value which is "${HOME}/.dvdcss/" under Unix and 91 | * "C:\Documents and Settings\$USER\Application Data\dvdcss\" under Win32. 92 | * The special value "off" disables caching. 93 | */ 94 | 95 | /* 96 | * Preamble 97 | */ 98 | #include "config.h" 99 | 100 | #include 101 | #include 102 | #include 103 | #include 104 | #include 105 | #include 106 | #ifdef HAVE_SYS_PARAM_H 107 | # include 108 | #endif 109 | #ifdef HAVE_PWD_H 110 | # include 111 | #endif 112 | #include 113 | #include 114 | 115 | #ifdef HAVE_UNISTD_H 116 | # include 117 | #endif 118 | 119 | #ifdef _WIN32 120 | # include 121 | # include 122 | #endif 123 | 124 | #include "dvdcss/dvdcss.h" 125 | 126 | #include "common.h" 127 | #include "css.h" 128 | #include "libdvdcss.h" 129 | #include "ioctl.h" 130 | #include "device.h" 131 | 132 | #ifdef HAVE_BROKEN_MKDIR 133 | #include 134 | #define mkdir(a, b) _mkdir(a) 135 | #endif 136 | 137 | #define CACHE_TAG_NAME "CACHEDIR.TAG" 138 | 139 | #define STRING_KEY_SIZE (DVD_KEY_SIZE * 2) 140 | #define INTERESTING_SECTOR 16 141 | #define DISC_TITLE_OFFSET 40 142 | #define DISC_TITLE_LENGTH 32 143 | #define MANUFACTURING_DATE_OFFSET 813 144 | #define MANUFACTURING_DATE_LENGTH 16 145 | 146 | #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) 147 | extern char* uwp_getenv(const char* n); 148 | size_t uwp_cachepath(char *buffer, size_t cch); 149 | #define getenv uwp_getenv 150 | #endif 151 | 152 | static int exists_or_mkdir( const char *path, int perm ) 153 | { 154 | /* mkdir() may return an error if making the directory would fail, 155 | * even if the directory exists, so use stat() to test for existence 156 | * before trying to make the directory. */ 157 | struct stat st; 158 | if( stat(path, &st) ) 159 | return mkdir(path, perm); 160 | return 0; 161 | } 162 | 163 | static dvdcss_t dvdcss_open_common ( const char *psz_target, void *p_stream, 164 | dvdcss_stream_cb *p_stream_cb ); 165 | static void set_verbosity( dvdcss_t dvdcss ) 166 | { 167 | const char *psz_verbose = getenv( "DVDCSS_VERBOSE" ); 168 | 169 | dvdcss->b_debug = 0; 170 | dvdcss->b_errors = 0; 171 | 172 | if( psz_verbose != NULL ) 173 | { 174 | int i = atoi( psz_verbose ); 175 | 176 | if( i >= 2 ) 177 | dvdcss->b_debug = 1; 178 | if( i >= 1 ) 179 | dvdcss->b_errors = 1; 180 | } 181 | } 182 | 183 | static int set_access_method( dvdcss_t dvdcss ) 184 | { 185 | const char *psz_method = getenv( "DVDCSS_METHOD" ); 186 | 187 | if( !psz_method ) 188 | return 0; 189 | 190 | if( !strncmp( psz_method, "key", 4 ) ) 191 | { 192 | dvdcss->i_method = DVDCSS_METHOD_KEY; 193 | } 194 | else if( !strncmp( psz_method, "disc", 5 ) ) 195 | { 196 | dvdcss->i_method = DVDCSS_METHOD_DISC; 197 | } 198 | else if( !strncmp( psz_method, "title", 5 ) ) 199 | { 200 | dvdcss->i_method = DVDCSS_METHOD_TITLE; 201 | } 202 | else 203 | { 204 | print_error( dvdcss, "unknown decryption method %s, please choose " 205 | "from 'title', 'key' or 'disc'", psz_method ); 206 | return -1; 207 | } 208 | return 0; 209 | } 210 | 211 | static int set_cache_directory( dvdcss_t dvdcss ) 212 | { 213 | char *psz_cache = getenv( "DVDCSS_CACHE" ); 214 | 215 | if( psz_cache && !strcmp( psz_cache, "off" ) ) 216 | { 217 | return -1; 218 | } 219 | 220 | if( psz_cache == NULL || psz_cache[0] == '\0' ) 221 | { 222 | #ifdef _WIN32 223 | char psz_home[PATH_MAX]; 224 | #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) 225 | if (uwp_cachepath(psz_home, PATH_MAX)) 226 | #else 227 | /* Cache our keys in 228 | * C:\Documents and Settings\$USER\Application Data\dvdcss\ */ 229 | if (SHGetFolderPathA (NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 230 | NULL, SHGFP_TYPE_CURRENT, psz_home ) == S_OK) 231 | #endif 232 | { 233 | snprintf( dvdcss->psz_cachefile, PATH_MAX, "%s\\dvdcss", psz_home ); 234 | dvdcss->psz_cachefile[PATH_MAX - 1] = '\0'; 235 | psz_cache = dvdcss->psz_cachefile; 236 | } 237 | #else 238 | #ifdef __ANDROID__ 239 | /* $HOME is not writable on __ANDROID__ so we have to create a custom 240 | * directory in userland */ 241 | char *psz_home = "/sdcard/Android/data/org.videolan.dvdcss"; 242 | 243 | int i_ret = exists_or_mkdir( psz_home, 0755 ); 244 | if( i_ret < 0 && errno != EEXIST ) 245 | { 246 | print_error( dvdcss, "failed creating home directory" ); 247 | psz_home = NULL; 248 | } 249 | #else 250 | char *psz_home = NULL; 251 | #ifdef HAVE_PWD_H 252 | struct passwd *p_pwd; 253 | 254 | /* Try looking in password file for home dir. */ 255 | p_pwd = getpwuid(getuid()); 256 | if( p_pwd && p_pwd->pw_dir && p_pwd->pw_dir[ 0 ] ) 257 | { 258 | psz_home = p_pwd->pw_dir; 259 | } 260 | #endif /* HAVE_PWD_H */ 261 | 262 | #endif /* __ANDROID__ */ 263 | 264 | if( psz_home == NULL ) 265 | { 266 | psz_home = getenv( "HOME" ); 267 | } 268 | 269 | /* Cache our keys in ${HOME}/.dvdcss/ */ 270 | if( psz_home && psz_home[ 0 ] ) 271 | { 272 | int home_pos = 0; 273 | 274 | #ifdef __OS2__ 275 | if( *psz_home == '/' || *psz_home == '\\') 276 | { 277 | const char *psz_unixroot = getenv("UNIXROOT"); 278 | 279 | if( psz_unixroot && 280 | psz_unixroot[0] && 281 | psz_unixroot[1] == ':' && 282 | psz_unixroot[2] == '\0') 283 | { 284 | strcpy( dvdcss->psz_cachefile, psz_unixroot ); 285 | home_pos = 2; 286 | } 287 | } 288 | #endif /* __OS2__ */ 289 | snprintf( dvdcss->psz_cachefile + home_pos, PATH_MAX - home_pos, 290 | "%s/.dvdcss", psz_home ); 291 | dvdcss->psz_cachefile[PATH_MAX - 1] = '\0'; 292 | psz_cache = dvdcss->psz_cachefile; 293 | } 294 | #endif /* ! defined( _WIN32 ) */ 295 | } 296 | else 297 | { 298 | strncpy( dvdcss->psz_cachefile, psz_cache, PATH_MAX ); 299 | dvdcss->psz_cachefile[PATH_MAX - 1] = '\0'; 300 | } 301 | 302 | /* Check that there is enough space for the cache directory path and the 303 | * block filename. The +1s are path separators. */ 304 | if( psz_cache && strlen( psz_cache ) + 1 + DISC_TITLE_LENGTH + 1 + 305 | MANUFACTURING_DATE_LENGTH + 1 + STRING_KEY_SIZE + 1 + 306 | sizeof(CACHE_TAG_NAME) > PATH_MAX ) 307 | { 308 | print_error( dvdcss, "cache directory name is too long" ); 309 | return -1; 310 | } 311 | return 0; 312 | } 313 | 314 | static int init_cache_dir( dvdcss_t dvdcss ) 315 | { 316 | static const char psz_tag[] = 317 | "Signature: 8a477f597d28d172789f06886806bc55\r\n" 318 | "# This file is a cache directory tag created by libdvdcss.\r\n" 319 | "# For information about cache directory tags, see:\r\n" 320 | "# http://www.brynosaurus.com/cachedir/\r\n"; 321 | char psz_tagfile[PATH_MAX]; 322 | int i_fd, i_ret; 323 | 324 | i_ret = exists_or_mkdir( dvdcss->psz_cachefile, 0755 ); 325 | if( i_ret < 0 && errno != EEXIST ) 326 | { 327 | print_error( dvdcss, "failed creating cache directory '%s'", dvdcss->psz_cachefile ); 328 | dvdcss->psz_cachefile[0] = '\0'; 329 | return -1; 330 | } 331 | 332 | i_ret = snprintf( psz_tagfile, PATH_MAX, "%s/" CACHE_TAG_NAME, 333 | dvdcss->psz_cachefile ); 334 | if ( i_ret < 0 || i_ret >= PATH_MAX) 335 | { 336 | if ( i_ret < 0) 337 | print_error( dvdcss, "failed to compose cache directory tag path"); 338 | else 339 | print_error( dvdcss, "cache directory tag path too long: %s/" CACHE_TAG_NAME, 340 | dvdcss->psz_cachefile ); 341 | dvdcss->psz_cachefile[0] = '\0'; 342 | return -1; 343 | } 344 | 345 | i_fd = open( psz_tagfile, O_RDWR|O_CREAT, 0644 ); 346 | if( i_fd >= 0 ) 347 | { 348 | ssize_t len = strlen(psz_tag); 349 | if( write( i_fd, psz_tag, len ) < len ) 350 | { 351 | print_error( dvdcss, 352 | "Error writing cache directory tag, continuing..\n" ); 353 | } 354 | close( i_fd ); 355 | } 356 | return 0; 357 | } 358 | 359 | static void create_cache_subdir( dvdcss_t dvdcss ) 360 | { 361 | uint8_t p_sector[DVDCSS_BLOCK_SIZE]; 362 | char psz_key[STRING_KEY_SIZE + 1]; 363 | char *psz_title; 364 | uint8_t *psz_serial; 365 | int i, i_ret; 366 | 367 | /* We read sector 0. If it starts with 0x000001ba (BE), we are 368 | * reading a VOB file, and we should not cache anything. */ 369 | 370 | i_ret = dvdcss->pf_seek( dvdcss, 0 ); 371 | if( i_ret != 0 ) 372 | { 373 | goto error; 374 | } 375 | 376 | i_ret = dvdcss->pf_read( dvdcss, p_sector, 1 ); 377 | if( i_ret != 1 ) 378 | { 379 | goto error; 380 | } 381 | 382 | if( p_sector[0] == 0x00 && p_sector[1] == 0x00 383 | && p_sector[2] == 0x01 && p_sector[3] == 0xba ) 384 | { 385 | goto error; 386 | } 387 | 388 | /* The data we are looking for is at sector 16 (32768 bytes): 389 | * - offset 40: disc title (32 uppercase chars) 390 | * - offset 813: manufacturing date + serial no (16 digits) */ 391 | 392 | i_ret = dvdcss->pf_seek( dvdcss, INTERESTING_SECTOR ); 393 | if( i_ret != INTERESTING_SECTOR ) 394 | { 395 | goto error; 396 | } 397 | 398 | i_ret = dvdcss->pf_read( dvdcss, p_sector, 1 ); 399 | if( i_ret != 1 ) 400 | { 401 | goto error; 402 | } 403 | 404 | /* Get the disc title */ 405 | psz_title = (char *)p_sector + DISC_TITLE_OFFSET; 406 | psz_title[DISC_TITLE_LENGTH] = '\0'; 407 | 408 | for( i = 0; i < DISC_TITLE_LENGTH; i++ ) 409 | { 410 | if( psz_title[i] <= ' ' ) 411 | { 412 | psz_title[i] = '\0'; 413 | break; 414 | } 415 | else if( psz_title[i] == '/' || psz_title[i] == '\\' ) 416 | { 417 | psz_title[i] = '-'; 418 | } 419 | } 420 | 421 | /* Get the date + serial */ 422 | psz_serial = p_sector + MANUFACTURING_DATE_OFFSET; 423 | psz_serial[MANUFACTURING_DATE_LENGTH] = '\0'; 424 | 425 | /* Check that all characters are digits, otherwise convert. */ 426 | for( i = 0 ; i < MANUFACTURING_DATE_LENGTH ; i++ ) 427 | { 428 | if( psz_serial[i] < '0' || psz_serial[i] > '9' ) 429 | { 430 | char psz_tmp[MANUFACTURING_DATE_LENGTH + 1]; 431 | sprintf( psz_tmp, 432 | "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", 433 | psz_serial[0], psz_serial[1], psz_serial[2], 434 | psz_serial[3], psz_serial[4], psz_serial[5], 435 | psz_serial[6], psz_serial[7] ); 436 | memcpy( psz_serial, psz_tmp, MANUFACTURING_DATE_LENGTH ); 437 | break; 438 | } 439 | } 440 | 441 | /* Get disk key, since some discs have the same title, manufacturing 442 | * date and serial number, but different keys. */ 443 | if( dvdcss->b_scrambled ) 444 | { 445 | for( i = 0; i < DVD_KEY_SIZE; i++ ) 446 | { 447 | sprintf( &psz_key[i * 2], "%.2x", dvdcss->css.p_disc_key[i] ); 448 | } 449 | psz_key[STRING_KEY_SIZE] = '\0'; 450 | } 451 | else 452 | { 453 | psz_key[0] = 0; 454 | } 455 | 456 | /* We have a disc name or ID, we can create the cache subdirectory. */ 457 | i = strlen( dvdcss->psz_cachefile ); 458 | i += sprintf( dvdcss->psz_cachefile + i, "/%s-%s-%s", 459 | psz_title, psz_serial, psz_key ); 460 | i_ret = exists_or_mkdir( dvdcss->psz_cachefile, 0755 ); 461 | if( i_ret < 0 && errno != EEXIST ) 462 | { 463 | print_error( dvdcss, "failed creating cache subdirectory" ); 464 | goto error; 465 | } 466 | i += sprintf( dvdcss->psz_cachefile + i, "/"); 467 | 468 | /* Pointer to the filename we will use. */ 469 | dvdcss->psz_block = dvdcss->psz_cachefile + i; 470 | 471 | print_debug( dvdcss, "Content Scrambling System (CSS) key cache dir: %s", 472 | dvdcss->psz_cachefile ); 473 | return; 474 | 475 | error: 476 | dvdcss->psz_cachefile[0] = '\0'; 477 | } 478 | 479 | static void init_cache( dvdcss_t dvdcss ) 480 | { 481 | /* Set CSS key cache directory. */ 482 | int i_ret = set_cache_directory( dvdcss ); 483 | if ( i_ret < 0 ) 484 | { 485 | return; 486 | } 487 | 488 | /* If the cache is enabled, initialize the cache directory. */ 489 | i_ret = init_cache_dir( dvdcss ); 490 | if ( i_ret < 0 ) 491 | { 492 | return; 493 | } 494 | 495 | /* If the cache is enabled, create a DVD-specific subdirectory. */ 496 | create_cache_subdir( dvdcss ); 497 | } 498 | 499 | /** 500 | * \brief Open a DVD device or directory and return a dvdcss instance. 501 | * 502 | * \param psz_target a string containing the target name, for instance 503 | * "/dev/hdc" or "E:" 504 | * \return a handle to a dvdcss instance or NULL on error. 505 | * 506 | * Initialize the \e libdvdcss library, open the requested DVD device or 507 | * directory, and return a handle to be used for all subsequent \e libdvdcss 508 | * calls. \e libdvdcss checks whether ioctls can be performed on the disc, 509 | * and when possible, the disc key is retrieved. 510 | */ 511 | LIBDVDCSS_EXPORT dvdcss_t dvdcss_open ( const char *psz_target ) 512 | { 513 | return dvdcss_open_common( psz_target, NULL, NULL ); 514 | } 515 | 516 | /** 517 | * \brief Open a DVD device using dvdcss_stream_cb. 518 | * 519 | * \param p_stream a private handle used by p_stream_cb 520 | * \param p_stream_cb a struct containing seek and read functions 521 | * \return a handle to a dvdcss instance or NULL on error. 522 | * 523 | * \see dvdcss_open() 524 | */ 525 | LIBDVDCSS_EXPORT dvdcss_t dvdcss_open_stream ( void *p_stream, 526 | dvdcss_stream_cb *p_stream_cb ) 527 | { 528 | return dvdcss_open_common( NULL, p_stream, p_stream_cb ); 529 | } 530 | 531 | static dvdcss_t dvdcss_open_common ( const char *psz_target, void *p_stream, 532 | dvdcss_stream_cb *p_stream_cb ) 533 | { 534 | int i_ret; 535 | 536 | /* Allocate the library structure. */ 537 | dvdcss_t dvdcss = malloc( sizeof( *dvdcss ) ); 538 | if( dvdcss == NULL ) 539 | { 540 | return NULL; 541 | } 542 | 543 | if( psz_target == NULL && 544 | ( p_stream == NULL || p_stream_cb == NULL ) ) 545 | { 546 | dvdcss->psz_device = NULL; 547 | goto error; 548 | } 549 | 550 | /* Initialize structure with default values. */ 551 | dvdcss->i_fd = -1; 552 | dvdcss->i_pos = 0; 553 | dvdcss->p_titles = NULL; 554 | dvdcss->psz_device = psz_target ? strdup( psz_target ) : NULL; 555 | dvdcss->psz_error = "no error"; 556 | dvdcss->i_method = DVDCSS_METHOD_KEY; 557 | dvdcss->psz_cachefile[0] = '\0'; 558 | 559 | dvdcss->p_stream = p_stream; 560 | dvdcss->p_stream_cb = p_stream_cb; 561 | 562 | /* Set library verbosity from DVDCSS_VERBOSE environment variable. */ 563 | set_verbosity( dvdcss ); 564 | 565 | /* Set DVD access method from DVDCSS_METHOD environment variable. */ 566 | if( set_access_method( dvdcss ) < 0 ) 567 | { 568 | goto error; 569 | } 570 | 571 | /* Open device. */ 572 | dvdcss_check_device( dvdcss ); 573 | i_ret = dvdcss_open_device( dvdcss ); 574 | if( i_ret < 0 ) 575 | { 576 | goto error; 577 | } 578 | 579 | dvdcss->b_scrambled = 1; /* Assume the worst */ 580 | dvdcss->b_ioctls = dvdcss_use_ioctls( dvdcss ); 581 | 582 | if( dvdcss->b_ioctls ) 583 | { 584 | i_ret = dvdcss_test( dvdcss ); 585 | 586 | if( i_ret == -3 ) 587 | { 588 | print_debug( dvdcss, "scrambled disc on a region-free RPC-II " 589 | "drive: possible failure, but continuing " 590 | "anyway" ); 591 | } 592 | else if( i_ret < 0 ) 593 | { 594 | /* Disable the CSS ioctls and hope that it works? */ 595 | print_debug( dvdcss, 596 | "could not check whether the disc was scrambled" ); 597 | dvdcss->b_ioctls = 0; 598 | } 599 | else 600 | { 601 | print_debug( dvdcss, i_ret ? "disc is scrambled" 602 | : "disc is unscrambled" ); 603 | dvdcss->b_scrambled = i_ret; 604 | } 605 | } 606 | 607 | memset( dvdcss->css.p_disc_key, 0, DVD_KEY_SIZE ); 608 | /* If disc is CSS protected and the ioctls work, authenticate the drive */ 609 | if( dvdcss->b_scrambled && dvdcss->b_ioctls ) 610 | { 611 | i_ret = dvdcss_disckey( dvdcss ); 612 | 613 | if( i_ret < 0 ) 614 | { 615 | print_debug( dvdcss, "could not get disc key" ); 616 | } 617 | } 618 | 619 | init_cache( dvdcss ); 620 | 621 | /* Seek to the beginning, just for safety. */ 622 | dvdcss->pf_seek( dvdcss, 0 ); 623 | 624 | return dvdcss; 625 | 626 | error: 627 | free( dvdcss->psz_device ); 628 | free( dvdcss ); 629 | return NULL; 630 | } 631 | 632 | /** 633 | * \brief Return a string containing the last error that occurred in the 634 | * given \e libdvdcss instance. 635 | * 636 | * \param dvdcss a \e libdvdcss instance 637 | * \return a NULL-terminated string containing the last error message. 638 | * 639 | * Return a string with the last error message produced by \e libdvdcss. 640 | * Useful to conveniently format error messages in external applications. 641 | */ 642 | LIBDVDCSS_EXPORT const char * dvdcss_error ( const dvdcss_t dvdcss ) 643 | { 644 | return dvdcss->psz_error; 645 | } 646 | 647 | /** 648 | * \brief Seek in the disc and change the current key if requested. 649 | * 650 | * \param dvdcss a \e libdvdcss instance 651 | * \param i_blocks an absolute block offset to seek to 652 | * \param i_flags #DVDCSS_NOFLAGS, optionally ORed with one of #DVDCSS_SEEK_KEY 653 | * or #DVDCSS_SEEK_MPEG 654 | * \return the new position in blocks or a negative value in case an error 655 | * happened. 656 | * 657 | * This function seeks to the requested position, in logical blocks. 658 | * 659 | * You typically set \p i_flags to #DVDCSS_NOFLAGS when seeking in a .IFO. 660 | * 661 | * If #DVDCSS_SEEK_MPEG is specified in \p i_flags and if \e libdvdcss finds it 662 | * reasonable to do so (i.e., if the dvdcss method is not "title"), the current 663 | * title key will be checked and a new one will be calculated if necessary. 664 | * This flag is typically used when reading data from a .VOB file. 665 | * 666 | * If #DVDCSS_SEEK_KEY is specified, the title key will always be checked, 667 | * even with the "title" method. This flag is typically used when seeking 668 | * in a new title. 669 | */ 670 | LIBDVDCSS_EXPORT int dvdcss_seek ( dvdcss_t dvdcss, int i_blocks, int i_flags ) 671 | { 672 | /* title cracking method is too slow to be used at each seek */ 673 | if( ( ( i_flags & DVDCSS_SEEK_MPEG ) 674 | && ( dvdcss->i_method != DVDCSS_METHOD_TITLE ) ) 675 | || ( i_flags & DVDCSS_SEEK_KEY ) ) 676 | { 677 | /* check the title key */ 678 | if( dvdcss_title( dvdcss, i_blocks ) ) 679 | { 680 | return -1; 681 | } 682 | } 683 | 684 | return dvdcss->pf_seek( dvdcss, i_blocks ); 685 | } 686 | 687 | /** 688 | * \brief Read from the disc and decrypt data if requested. 689 | * 690 | * \param dvdcss a \e libdvdcss instance 691 | * \param p_buffer a buffer that will contain the data read from the disc 692 | * \param i_blocks the amount of blocks to read 693 | * \param i_flags #DVDCSS_NOFLAGS, optionally ORed with #DVDCSS_READ_DECRYPT 694 | * \return the amount of blocks read or a negative value in case an 695 | * error happened. 696 | * 697 | * Read \p i_blocks logical blocks from the DVD. 698 | * 699 | * You typically set \p i_flags to #DVDCSS_NOFLAGS when reading data from a 700 | * .IFO file on the DVD. 701 | * 702 | * If #DVDCSS_READ_DECRYPT is specified in \p i_flags, dvdcss_read() will 703 | * automatically decrypt scrambled sectors. This flag is typically used when 704 | * reading data from a .VOB file on the DVD. It has no effect on unscrambled 705 | * discs or unscrambled sectors and can be safely used on those. 706 | * 707 | * \warning dvdcss_read() expects to be able to write \p i_blocks * 708 | * #DVDCSS_BLOCK_SIZE bytes into \p p_buffer. 709 | */ 710 | LIBDVDCSS_EXPORT int dvdcss_read ( dvdcss_t dvdcss, void *p_buffer, 711 | int i_blocks, 712 | int i_flags ) 713 | { 714 | uint8_t *_p_buffer = p_buffer; 715 | int i_ret, i_index; 716 | 717 | i_ret = dvdcss->pf_read( dvdcss, _p_buffer, i_blocks ); 718 | 719 | if( i_ret <= 0 720 | || !dvdcss->b_scrambled 721 | || !(i_flags & DVDCSS_READ_DECRYPT) ) 722 | { 723 | return i_ret; 724 | } 725 | 726 | if( ! memcmp( dvdcss->css.p_title_key, "\0\0\0\0\0", 5 ) ) 727 | { 728 | /* For what we believe is an unencrypted title, 729 | * check that there are no encrypted blocks */ 730 | for( i_index = i_ret; i_index; i_index-- ) 731 | { 732 | if( _p_buffer[0x14] & 0x30 ) 733 | { 734 | print_error( dvdcss, "no key but found encrypted block" ); 735 | /* Only return the initial range of unscrambled blocks? */ 736 | /* or fail completely? return 0; */ 737 | break; 738 | } 739 | _p_buffer = _p_buffer + DVDCSS_BLOCK_SIZE; 740 | } 741 | } 742 | else 743 | { 744 | /* Decrypt the blocks we managed to read */ 745 | for( i_index = i_ret; i_index; i_index-- ) 746 | { 747 | dvdcss_unscramble( dvdcss->css.p_title_key, _p_buffer ); 748 | _p_buffer[0x14] &= 0x8f; 749 | _p_buffer = _p_buffer + DVDCSS_BLOCK_SIZE; 750 | } 751 | } 752 | 753 | return i_ret; 754 | } 755 | 756 | /** 757 | * \brief Read data from the disc into multiple buffers and decrypt data if 758 | * requested. 759 | * 760 | * \param dvdcss a \e libdvdcss instance 761 | * \param p_iovec a pointer to an array of iovec structures that will contain 762 | * the data read from the disc 763 | * \param i_blocks the amount of blocks to read 764 | * \param i_flags #DVDCSS_NOFLAGS, optionally ORed with #DVDCSS_READ_DECRYPT 765 | * \return the amount of blocks read or a negative value in case an 766 | * error happened. 767 | * 768 | * Read \p i_blocks logical blocks from the DVD and write them 769 | * to an array of iovec structures. 770 | * 771 | * You typically set \p i_flags to #DVDCSS_NOFLAGS when reading data from a 772 | * .IFO file on the DVD. 773 | * 774 | * If #DVDCSS_READ_DECRYPT is specified in \p i_flags, dvdcss_readv() will 775 | * automatically decrypt scrambled sectors. This flag is typically used when 776 | * reading data from a .VOB file on the DVD. It has no effect on unscrambled 777 | * discs or unscrambled sectors and can be safely used on those. 778 | * 779 | * \warning dvdcss_readv() expects to be able to write \p i_blocks * 780 | * #DVDCSS_BLOCK_SIZE bytes into the buffers pointed by \p p_iovec. 781 | * Moreover, all iov_len members of the iovec structures should be 782 | * multiples of #DVDCSS_BLOCK_SIZE. 783 | */ 784 | LIBDVDCSS_EXPORT int dvdcss_readv ( dvdcss_t dvdcss, void *p_iovec, 785 | int i_blocks, 786 | int i_flags ) 787 | { 788 | struct iovec *_p_iovec = p_iovec; 789 | int i_ret, i_index; 790 | void *iov_base; 791 | size_t iov_len; 792 | 793 | i_ret = dvdcss->pf_readv( dvdcss, _p_iovec, i_blocks ); 794 | 795 | if( i_ret <= 0 796 | || !dvdcss->b_scrambled 797 | || !(i_flags & DVDCSS_READ_DECRYPT) ) 798 | { 799 | return i_ret; 800 | } 801 | 802 | /* Initialize loop for decryption */ 803 | iov_base = _p_iovec->iov_base; 804 | iov_len = _p_iovec->iov_len; 805 | 806 | /* Decrypt the blocks we managed to read */ 807 | for( i_index = i_ret; i_index; i_index-- ) 808 | { 809 | /* Check that iov_len is a multiple of 2048 */ 810 | if( iov_len & 0x7ff ) 811 | { 812 | return -1; 813 | } 814 | 815 | while( iov_len == 0 ) 816 | { 817 | _p_iovec++; 818 | iov_base = _p_iovec->iov_base; 819 | iov_len = _p_iovec->iov_len; 820 | } 821 | 822 | dvdcss_unscramble( dvdcss->css.p_title_key, iov_base ); 823 | ((uint8_t*)iov_base)[0x14] &= 0x8f; 824 | 825 | iov_base = (uint8_t*)iov_base + DVDCSS_BLOCK_SIZE; 826 | iov_len -= DVDCSS_BLOCK_SIZE; 827 | } 828 | 829 | return i_ret; 830 | } 831 | 832 | /** 833 | * \brief Clean up library state and structures. 834 | * 835 | * \param dvdcss a \e libdvdcss instance 836 | * \return zero in case of success, a negative value otherwise. 837 | * 838 | * Close the DVD device and free all the memory allocated by \e libdvdcss. 839 | * On return, the #dvdcss_t is invalidated and may not be used again. 840 | */ 841 | LIBDVDCSS_EXPORT int dvdcss_close ( dvdcss_t dvdcss ) 842 | { 843 | struct dvd_title *p_title; 844 | int i_ret; 845 | 846 | /* Free our list of keys */ 847 | p_title = dvdcss->p_titles; 848 | while( p_title ) 849 | { 850 | struct dvd_title *p_tmptitle = p_title->p_next; 851 | free( p_title ); 852 | p_title = p_tmptitle; 853 | } 854 | 855 | i_ret = dvdcss_close_device( dvdcss ); 856 | 857 | free( dvdcss->psz_device ); 858 | free( dvdcss ); 859 | 860 | return i_ret; 861 | } 862 | 863 | /** 864 | * \brief Detect whether or not a DVD is scrambled 865 | * 866 | * \param dvdcss a \e libdvdcss instance. 867 | * \return 1 if the DVD is scrambled, 0 otherwise. 868 | */ 869 | LIBDVDCSS_EXPORT int dvdcss_is_scrambled ( dvdcss_t dvdcss ) 870 | { 871 | return dvdcss->b_scrambled; 872 | } 873 | -------------------------------------------------------------------------------- /src/device.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * device.h: DVD device access 3 | ***************************************************************************** 4 | * Copyright (C) 1998-2006 VideoLAN 5 | * 6 | * Authors: Stéphane Borel 7 | * Sam Hocevar 8 | * Håkan Hjort 9 | * 10 | * libdvdcss is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * libdvdcss is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License along 21 | * with libdvdcss; if not, write to the Free Software Foundation, Inc., 22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 23 | *****************************************************************************/ 24 | 25 | /***************************************************************************** 26 | * Preamble 27 | *****************************************************************************/ 28 | #include "config.h" 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #ifdef HAVE_ERRNO_H 35 | # include 36 | #endif 37 | #include 38 | #include 39 | #ifdef HAVE_SYS_PARAM_H 40 | # include 41 | #endif 42 | #include 43 | 44 | #ifdef HAVE_UNISTD_H 45 | # include 46 | #endif 47 | 48 | #ifdef DARWIN_DVD_IOCTL 49 | # include 50 | # include 51 | # include 52 | # include 53 | # include 54 | # include 55 | # include 56 | #endif 57 | 58 | #ifdef __OS2__ 59 | # define INCL_DOS 60 | # define INCL_DOSDEVIOCTL 61 | # include 62 | # include /* setmode() */ 63 | # include /* O_BINARY */ 64 | #endif 65 | 66 | #ifdef _WIN32 67 | # include 68 | #endif 69 | 70 | #include "dvdcss/dvdcss.h" 71 | 72 | #include "common.h" 73 | #include "css.h" 74 | #include "libdvdcss.h" 75 | #include "ioctl.h" 76 | #include "device.h" 77 | 78 | /***************************************************************************** 79 | * Device reading prototypes 80 | *****************************************************************************/ 81 | static int libc_open ( dvdcss_t, const char * ); 82 | static int libc_seek ( dvdcss_t, int ); 83 | static int libc_read ( dvdcss_t, void *, int ); 84 | static int libc_readv ( dvdcss_t, const struct iovec *, int ); 85 | 86 | static int stream_seek ( dvdcss_t, int ); 87 | static int stream_read ( dvdcss_t, void *, int ); 88 | static int stream_readv ( dvdcss_t, const struct iovec *, int ); 89 | 90 | #ifdef _WIN32 91 | static int win2k_open ( dvdcss_t, const char * ); 92 | static int win2k_seek ( dvdcss_t, int ); 93 | static int win2k_read ( dvdcss_t, void *, int ); 94 | static int win2k_readv ( dvdcss_t, const struct iovec *, int ); 95 | 96 | #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) 97 | extern char* uwp_getenv(const char* n); 98 | size_t uwp_cachepath(char *buffer, size_t cch); 99 | #define getenv uwp_getenv 100 | #endif 101 | 102 | #elif defined( __OS2__ ) 103 | static int os2_open ( dvdcss_t, const char * ); 104 | #endif 105 | 106 | int dvdcss_use_ioctls( dvdcss_t dvdcss ) 107 | { 108 | if( dvdcss->p_stream ) 109 | return 0; 110 | 111 | #if defined( _WIN32 ) 112 | if( dvdcss->b_file ) 113 | { 114 | return 0; 115 | } 116 | 117 | /* FIXME: implement this for Windows */ 118 | return 1; 119 | #elif defined( __OS2__ ) 120 | ULONG ulMode; 121 | 122 | if( DosQueryFHState( dvdcss->i_fd, &ulMode ) != 0 ) 123 | return 1; /* What to do? Be conservative and try to use the ioctls */ 124 | 125 | if( ulMode & OPEN_FLAGS_DASD ) 126 | return 1; 127 | 128 | return 0; 129 | #elif defined(__APPLE__) && (defined(__arm__) || defined(__aarch64__)) 130 | return 0; 131 | #else 132 | struct stat fileinfo; 133 | int ret; 134 | 135 | ret = fstat( dvdcss->i_fd, &fileinfo ); 136 | if( ret < 0 ) 137 | { 138 | return 1; /* What to do? Be conservative and try to use the ioctls */ 139 | } 140 | 141 | /* Complete this list and check that we test for the right things 142 | * (I've assumed for all OSs that 'r', (raw) device, are char devices 143 | * and those that don't contain/use an 'r' in the name are block devices) 144 | * 145 | * Linux needs a block device 146 | * Solaris needs a char device 147 | * Darwin needs a char device 148 | * OpenBSD needs a char device 149 | * NetBSD needs a char device 150 | * FreeBSD can use either the block or the char device 151 | */ 152 | 153 | /* Check if this is a block/char device */ 154 | if( S_ISBLK( fileinfo.st_mode ) || 155 | S_ISCHR( fileinfo.st_mode ) ) 156 | { 157 | return 1; 158 | } 159 | else 160 | { 161 | return 0; 162 | } 163 | #endif 164 | } 165 | 166 | void dvdcss_check_device ( dvdcss_t dvdcss ) 167 | { 168 | #if defined( _WIN32 ) 169 | DWORD drives; 170 | int i; 171 | #elif defined( DARWIN_DVD_IOCTL ) 172 | io_object_t next_media; 173 | mach_port_t master_port; 174 | kern_return_t kern_result; 175 | io_iterator_t media_iterator; 176 | CFMutableDictionaryRef classes_to_match; 177 | #elif defined( __OS2__ ) 178 | #pragma pack( 1 ) 179 | struct 180 | { 181 | BYTE bCmdInfo; 182 | BYTE bDrive; 183 | } param; 184 | 185 | struct 186 | { 187 | BYTE abEBPB[31]; 188 | USHORT usCylinders; 189 | BYTE bDevType; 190 | USHORT usDevAttr; 191 | } data; 192 | #pragma pack() 193 | 194 | ULONG ulParamLen; 195 | ULONG ulDataLen; 196 | ULONG rc; 197 | 198 | int i; 199 | #else 200 | const char *ppsz_devices[] = { "/dev/dvd", "/dev/cdrom", "/dev/hdc", NULL }; 201 | int i, i_fd; 202 | #endif 203 | 204 | /* If the device name is non-NULL or stream is set, return. */ 205 | if( (dvdcss->psz_device && dvdcss->psz_device[0]) || dvdcss->p_stream ) 206 | { 207 | return; 208 | } 209 | 210 | #if defined( _WIN32 ) 211 | drives = GetLogicalDrives(); 212 | 213 | for( i = 0; drives; i++ ) 214 | { 215 | char psz_device[5]; 216 | DWORD cur = 1 << i; 217 | UINT i_ret; 218 | 219 | if( (drives & cur) == 0 ) 220 | { 221 | continue; 222 | } 223 | drives &= ~cur; 224 | 225 | sprintf( psz_device, "%c:\\", 'A' + i ); 226 | i_ret = GetDriveTypeA( psz_device ); 227 | if( i_ret != DRIVE_CDROM ) 228 | { 229 | continue; 230 | } 231 | 232 | /* Remove trailing backslash */ 233 | psz_device[2] = '\0'; 234 | 235 | /* FIXME: we want to differentiate between CD and DVD drives 236 | * using DeviceIoControl() */ 237 | print_debug( dvdcss, "defaulting to drive `%s'", psz_device ); 238 | free( dvdcss->psz_device ); 239 | dvdcss->psz_device = strdup( psz_device ); 240 | return; 241 | } 242 | #elif defined( DARWIN_DVD_IOCTL ) 243 | 244 | kern_result = IOMasterPort( MACH_PORT_NULL, &master_port ); 245 | if( kern_result != KERN_SUCCESS ) 246 | { 247 | return; 248 | } 249 | 250 | classes_to_match = IOServiceMatching( kIODVDMediaClass ); 251 | if( classes_to_match == NULL ) 252 | { 253 | return; 254 | } 255 | 256 | CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ), 257 | kCFBooleanTrue ); 258 | 259 | kern_result = IOServiceGetMatchingServices( master_port, classes_to_match, 260 | &media_iterator ); 261 | if( kern_result != KERN_SUCCESS ) 262 | { 263 | return; 264 | } 265 | 266 | next_media = IOIteratorNext( media_iterator ); 267 | for( ; ; ) 268 | { 269 | char psz_buf[0x32]; 270 | size_t i_pathlen; 271 | CFTypeRef psz_path; 272 | 273 | next_media = IOIteratorNext( media_iterator ); 274 | if( next_media == 0 ) 275 | { 276 | break; 277 | } 278 | 279 | psz_path = IORegistryEntryCreateCFProperty( next_media, 280 | CFSTR( kIOBSDNameKey ), 281 | kCFAllocatorDefault, 282 | 0 ); 283 | if( psz_path == NULL ) 284 | { 285 | IOObjectRelease( next_media ); 286 | continue; 287 | } 288 | 289 | snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' ); 290 | i_pathlen = strlen( psz_buf ); 291 | 292 | if( CFStringGetCString( psz_path, 293 | (char*)&psz_buf + i_pathlen, 294 | sizeof(psz_buf) - i_pathlen, 295 | kCFStringEncodingASCII ) ) 296 | { 297 | print_debug( dvdcss, "defaulting to drive `%s'", psz_buf ); 298 | CFRelease( psz_path ); 299 | IOObjectRelease( next_media ); 300 | IOObjectRelease( media_iterator ); 301 | free( dvdcss->psz_device ); 302 | dvdcss->psz_device = strdup( psz_buf ); 303 | return; 304 | } 305 | 306 | CFRelease( psz_path ); 307 | 308 | IOObjectRelease( next_media ); 309 | } 310 | 311 | IOObjectRelease( media_iterator ); 312 | #elif defined( __OS2__ ) 313 | for( i = 0; i < 26; i++ ) 314 | { 315 | param.bCmdInfo = 0; 316 | param.bDrive = i; 317 | 318 | rc = DosDevIOCtl( ( HFILE )-1, IOCTL_DISK, DSK_GETDEVICEPARAMS, 319 | ¶m, sizeof( param ), &ulParamLen, 320 | &data, sizeof( data ), &ulDataLen ); 321 | 322 | if( rc == 0 ) 323 | { 324 | /* Check for removable and for cylinders */ 325 | if( ( data.usDevAttr & 1 ) == 0 && data.usCylinders == 0xFFFF ) 326 | { 327 | char psz_dvd[] = "A:"; 328 | 329 | psz_dvd[0] += i; 330 | 331 | print_debug( dvdcss, "defaulting to drive `%s'", psz_dvd ); 332 | free( dvdcss->psz_device ); 333 | dvdcss->psz_device = strdup( psz_dvd ); 334 | return; 335 | } 336 | } 337 | } 338 | #else 339 | for( i = 0; ppsz_devices[i]; i++ ) 340 | { 341 | i_fd = open( ppsz_devices[i], 0 ); 342 | if( i_fd != -1 ) 343 | { 344 | print_debug( dvdcss, "defaulting to drive `%s'", ppsz_devices[i] ); 345 | close( i_fd ); 346 | free( dvdcss->psz_device ); 347 | dvdcss->psz_device = strdup( ppsz_devices[i] ); 348 | return; 349 | } 350 | } 351 | #endif 352 | 353 | print_error( dvdcss, "could not find a suitable default drive" ); 354 | } 355 | 356 | int dvdcss_open_device ( dvdcss_t dvdcss ) 357 | { 358 | const char *psz_device = getenv( "DVDCSS_RAW_DEVICE" ); 359 | if( !psz_device ) 360 | { 361 | psz_device = dvdcss->psz_device; 362 | } 363 | print_debug( dvdcss, "opening target `%s'", psz_device ); 364 | 365 | #if defined( _WIN32 ) 366 | /* Initialize readv temporary buffer */ 367 | dvdcss->p_readv_buffer = NULL; 368 | dvdcss->i_readv_buf_size = 0; 369 | #endif 370 | 371 | /* if callback functions are initialized */ 372 | if( dvdcss->p_stream ) 373 | { 374 | print_debug( dvdcss, "using stream API for access" ); 375 | dvdcss->pf_seek = stream_seek; 376 | dvdcss->pf_read = stream_read; 377 | dvdcss->pf_readv = stream_readv; 378 | return 0; 379 | } 380 | 381 | #if defined( _WIN32 ) 382 | dvdcss->b_file = 1; 383 | /* If device is "X:" or "X:\", we are not actually opening a file. */ 384 | if (psz_device[0] && psz_device[1] == ':' && 385 | (!psz_device[2] || (psz_device[2] == '\\' && !psz_device[3]))) 386 | dvdcss->b_file = 0; 387 | 388 | if( !dvdcss->b_file ) 389 | { 390 | print_debug( dvdcss, "using Win2K API for access" ); 391 | dvdcss->pf_seek = win2k_seek; 392 | dvdcss->pf_read = win2k_read; 393 | dvdcss->pf_readv = win2k_readv; 394 | return win2k_open( dvdcss, psz_device ); 395 | } 396 | else 397 | #elif defined( __OS2__ ) 398 | /* If device is "X:" or "X:\", we are not actually opening a file. */ 399 | if( psz_device[0] && psz_device[1] == ':' && 400 | ( !psz_device[2] || ( psz_device[2] == '\\' && !psz_device[3] ) ) ) 401 | { 402 | print_debug( dvdcss, "using OS/2 API for access" ); 403 | dvdcss->pf_seek = libc_seek; 404 | dvdcss->pf_read = libc_read; 405 | dvdcss->pf_readv = libc_readv; 406 | return os2_open( dvdcss, psz_device ); 407 | } 408 | else 409 | #endif 410 | { 411 | print_debug( dvdcss, "using libc API for access" ); 412 | dvdcss->pf_seek = libc_seek; 413 | dvdcss->pf_read = libc_read; 414 | dvdcss->pf_readv = libc_readv; 415 | return libc_open( dvdcss, psz_device ); 416 | } 417 | } 418 | 419 | int dvdcss_close_device ( dvdcss_t dvdcss ) 420 | { 421 | if( dvdcss->p_stream ) 422 | { 423 | return 0; 424 | } 425 | 426 | #if defined( _WIN32 ) 427 | /* Free readv temporary buffer */ 428 | free( dvdcss->p_readv_buffer ); 429 | dvdcss->p_readv_buffer = NULL; 430 | dvdcss->i_readv_buf_size = 0; 431 | 432 | if( !dvdcss->b_file ) 433 | { 434 | CloseHandle( (HANDLE) dvdcss->i_fd ); 435 | } 436 | else if( !dvdcss->p_stream ) 437 | #endif 438 | { 439 | int i_ret = close( dvdcss->i_fd ); 440 | if( i_ret < 0 ) 441 | { 442 | print_error( dvdcss, "Failed to close fd, data loss possible." ); 443 | return i_ret; 444 | } 445 | } 446 | 447 | return 0; 448 | } 449 | 450 | /* Following functions are local */ 451 | 452 | /***************************************************************************** 453 | * Open commands. 454 | *****************************************************************************/ 455 | static int libc_open ( dvdcss_t dvdcss, const char *psz_device ) 456 | { 457 | #ifdef _WIN32 458 | int wlen; 459 | dvdcss->i_fd = -1; 460 | wlen = MultiByteToWideChar( CP_UTF8, 0, psz_device, -1, NULL, 0 ); 461 | if( wlen > 0 ) { 462 | wchar_t *wpath = (wchar_t*)malloc( sizeof(wchar_t) * wlen ); 463 | if( wpath ) { 464 | if( MultiByteToWideChar(CP_UTF8, 0, psz_device, -1, wpath, wlen ) ) { 465 | dvdcss->i_fd = _wopen( wpath, O_BINARY ); 466 | } 467 | free( wpath ); 468 | } 469 | } 470 | #else 471 | dvdcss->i_fd = open( psz_device, O_BINARY ); 472 | #endif 473 | 474 | if( dvdcss->i_fd == -1 ) 475 | { 476 | print_error( dvdcss, "failed to open device %s (%s)", 477 | psz_device, strerror(errno) ); 478 | return -1; 479 | } 480 | 481 | return 0; 482 | } 483 | 484 | #if defined( _WIN32 ) 485 | #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) 486 | HANDLE WINAPI CreateFileW(LPCWSTR lpFileName, 487 | DWORD dwDesiredAccess, 488 | DWORD dwShareMode, 489 | LPSECURITY_ATTRIBUTES lpSecurityAttributes, 490 | DWORD dwCreationDisposition, 491 | DWORD dwFlagsAndAttributes, 492 | HANDLE hTemplateFile) 493 | { 494 | CREATEFILE2_EXTENDED_PARAMETERS createExParams; 495 | createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); 496 | createExParams.dwFileAttributes = dwFlagsAndAttributes & 0xFFFF; 497 | createExParams.dwFileFlags = dwFlagsAndAttributes & 0xFFF00000; 498 | createExParams.dwSecurityQosFlags = dwFlagsAndAttributes & 0x000F00000; 499 | createExParams.lpSecurityAttributes = lpSecurityAttributes; 500 | createExParams.hTemplateFile = hTemplateFile; 501 | return CreateFile2(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, &createExParams); 502 | } 503 | extern size_t uwp_Utf8ToW(const char* src, wchar_t* buffer, int maxlen); 504 | 505 | static int win2k_open(dvdcss_t dvdcss, const char *psz_device) 506 | { 507 | char psz_dvd[7] = "\\\\.\\\0:"; 508 | psz_dvd[4] = psz_device[0]; 509 | wchar_t pathW[7]; 510 | uwp_Utf8ToW(psz_dvd, pathW, 8); 511 | 512 | /* To work around an M$ bug in IOCTL_DVD_READ_STRUCTURE, we need read 513 | * _and_ write access to the device (so we can make SCSI Pass Through 514 | * Requests). Unfortunately this is only allowed if you have 515 | * administrator privileges so we allow for a fallback method with 516 | * only read access to the device (in this case ioctl_ReadCopyright() 517 | * won't send back the right result). 518 | * (See Microsoft Q241374: Read and Write Access Required for SCSI 519 | * Pass Through Requests) */ 520 | dvdcss->i_fd = (int) 521 | CreateFileW(pathW, GENERIC_READ | GENERIC_WRITE, 522 | FILE_SHARE_READ | FILE_SHARE_WRITE, 523 | NULL, OPEN_EXISTING, 524 | FILE_FLAG_RANDOM_ACCESS, NULL); 525 | 526 | if ((HANDLE)dvdcss->i_fd == INVALID_HANDLE_VALUE) 527 | dvdcss->i_fd = (int) 528 | CreateFileW(pathW, GENERIC_READ, FILE_SHARE_READ, 529 | NULL, OPEN_EXISTING, 530 | FILE_FLAG_RANDOM_ACCESS, NULL); 531 | 532 | if ((HANDLE)dvdcss->i_fd == INVALID_HANDLE_VALUE) 533 | { 534 | print_error(dvdcss, "failed to open device %s", psz_device); 535 | return -1; 536 | } 537 | 538 | dvdcss->i_pos = 0; 539 | 540 | return 0; 541 | } 542 | #else 543 | static int win2k_open ( dvdcss_t dvdcss, const char *psz_device ) 544 | { 545 | char psz_dvd[7] = "\\\\.\\\0:"; 546 | psz_dvd[4] = psz_device[0]; 547 | 548 | /* To work around an M$ bug in IOCTL_DVD_READ_STRUCTURE, we need read 549 | * _and_ write access to the device (so we can make SCSI Pass Through 550 | * Requests). Unfortunately this is only allowed if you have 551 | * administrator privileges so we allow for a fallback method with 552 | * only read access to the device (in this case ioctl_ReadCopyright() 553 | * won't send back the right result). 554 | * (See Microsoft Q241374: Read and Write Access Required for SCSI 555 | * Pass Through Requests) */ 556 | dvdcss->i_fd = (int) 557 | CreateFile( psz_dvd, GENERIC_READ | GENERIC_WRITE, 558 | FILE_SHARE_READ | FILE_SHARE_WRITE, 559 | NULL, OPEN_EXISTING, 560 | FILE_FLAG_RANDOM_ACCESS, NULL ); 561 | 562 | if( (HANDLE) dvdcss->i_fd == INVALID_HANDLE_VALUE ) 563 | dvdcss->i_fd = (int) 564 | CreateFile( psz_dvd, GENERIC_READ, FILE_SHARE_READ, 565 | NULL, OPEN_EXISTING, 566 | FILE_FLAG_RANDOM_ACCESS, NULL ); 567 | 568 | if( (HANDLE) dvdcss->i_fd == INVALID_HANDLE_VALUE ) 569 | { 570 | print_error( dvdcss, "failed to open device %s", psz_device ); 571 | return -1; 572 | } 573 | 574 | dvdcss->i_pos = 0; 575 | 576 | return 0; 577 | } 578 | #endif 579 | #endif /* defined( _WIN32 ) */ 580 | 581 | #ifdef __OS2__ 582 | static int os2_open ( dvdcss_t dvdcss, const char *psz_device ) 583 | { 584 | char psz_dvd[] = "X:"; 585 | HFILE hfile; 586 | ULONG ulAction; 587 | ULONG rc; 588 | 589 | psz_dvd[0] = psz_device[0]; 590 | 591 | rc = DosOpenL( ( PSZ )psz_dvd, &hfile, &ulAction, 0, FILE_NORMAL, 592 | OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW, 593 | OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE | OPEN_FLAGS_DASD, 594 | NULL ); 595 | 596 | if( rc ) 597 | { 598 | print_error( dvdcss, "failed to open device %s", psz_device ); 599 | return -1; 600 | } 601 | 602 | setmode( hfile, O_BINARY ); 603 | 604 | dvdcss->i_fd = hfile; 605 | 606 | dvdcss->i_pos = 0; 607 | 608 | return 0; 609 | } 610 | #endif /* __OS2__ */ 611 | 612 | /***************************************************************************** 613 | * Seek commands. 614 | *****************************************************************************/ 615 | static int libc_seek( dvdcss_t dvdcss, int i_blocks ) 616 | { 617 | off_t i_seek; 618 | 619 | if( dvdcss->i_pos == i_blocks ) 620 | { 621 | /* We are already in position */ 622 | return i_blocks; 623 | } 624 | 625 | i_seek = (off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE; 626 | i_seek = lseek( dvdcss->i_fd, i_seek, SEEK_SET ); 627 | 628 | if( i_seek < 0 ) 629 | { 630 | print_error( dvdcss, "seek error" ); 631 | dvdcss->i_pos = -1; 632 | return i_seek; 633 | } 634 | 635 | dvdcss->i_pos = i_seek / DVDCSS_BLOCK_SIZE; 636 | 637 | return dvdcss->i_pos; 638 | } 639 | 640 | static int stream_seek( dvdcss_t dvdcss, int i_blocks ) 641 | { 642 | off_t i_seek = (off_t) i_blocks * (off_t) DVDCSS_BLOCK_SIZE; 643 | 644 | if( !dvdcss->p_stream_cb->pf_seek ) 645 | return -1; 646 | 647 | if( dvdcss->i_pos == i_blocks ) 648 | { 649 | /* We are already in position */ 650 | return i_blocks; 651 | } 652 | 653 | if( dvdcss->p_stream_cb->pf_seek( dvdcss->p_stream, i_seek ) != 0 ) 654 | { 655 | print_error( dvdcss, "seek error" ); 656 | dvdcss->i_pos = -1; 657 | return -1; 658 | } 659 | 660 | dvdcss->i_pos = i_blocks; 661 | 662 | return dvdcss->i_pos; 663 | } 664 | 665 | #if defined( _WIN32 ) 666 | static int win2k_seek( dvdcss_t dvdcss, int i_blocks ) 667 | { 668 | LARGE_INTEGER li_seek; 669 | 670 | if( dvdcss->i_pos == i_blocks ) 671 | { 672 | /* We are already in position */ 673 | return i_blocks; 674 | } 675 | 676 | li_seek.QuadPart = (LONGLONG)i_blocks * DVDCSS_BLOCK_SIZE; 677 | 678 | li_seek.LowPart = SetFilePointer( (HANDLE) dvdcss->i_fd, 679 | li_seek.LowPart, 680 | &li_seek.HighPart, FILE_BEGIN ); 681 | if( (li_seek.LowPart == INVALID_SET_FILE_POINTER) 682 | && GetLastError() != NO_ERROR) 683 | { 684 | dvdcss->i_pos = -1; 685 | return -1; 686 | } 687 | 688 | dvdcss->i_pos = li_seek.QuadPart / DVDCSS_BLOCK_SIZE; 689 | 690 | return dvdcss->i_pos; 691 | } 692 | #endif /* defined( _WIN32 ) */ 693 | 694 | /***************************************************************************** 695 | * Read commands. 696 | *****************************************************************************/ 697 | static int libc_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks ) 698 | { 699 | off_t i_size, i_ret, i_ret_blocks; 700 | 701 | i_size = (off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE; 702 | i_ret = 0; 703 | while (i_ret < i_size) 704 | { 705 | off_t i_r; 706 | i_r = read(dvdcss->i_fd, ((char*)p_buffer) + i_ret, i_size - i_ret); 707 | if (i_r < 0) 708 | { 709 | print_error(dvdcss, "read error"); 710 | dvdcss->i_pos = -1; 711 | return i_r; 712 | } 713 | if (i_r == 0) 714 | break; 715 | 716 | i_ret += i_r; 717 | } 718 | 719 | i_ret_blocks = i_ret / DVDCSS_BLOCK_SIZE; 720 | 721 | /* Handle partial reads */ 722 | if( i_ret != i_size ) 723 | { 724 | int i_seek, i_set_pos; 725 | 726 | i_set_pos = dvdcss->i_pos + i_ret_blocks; 727 | dvdcss->i_pos = -1; 728 | i_seek = libc_seek( dvdcss, i_set_pos ); 729 | if( i_seek < 0 ) 730 | { 731 | return i_seek; 732 | } 733 | 734 | /* We have to return now so that i_pos isn't clobbered */ 735 | return i_ret_blocks; 736 | } 737 | 738 | dvdcss->i_pos += i_ret_blocks; 739 | return i_ret_blocks; 740 | } 741 | 742 | static int stream_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks ) 743 | { 744 | off_t i_size, i_ret, i_ret_blocks; 745 | 746 | i_size = (off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE; 747 | 748 | if( !dvdcss->p_stream_cb->pf_read ) 749 | return -1; 750 | 751 | i_ret = dvdcss->p_stream_cb->pf_read( dvdcss->p_stream, p_buffer, i_size ); 752 | 753 | if( i_ret < 0 ) 754 | { 755 | print_error( dvdcss, "read error" ); 756 | dvdcss->i_pos = -1; 757 | return i_ret; 758 | } 759 | 760 | i_ret_blocks = i_ret / DVDCSS_BLOCK_SIZE; 761 | 762 | /* Handle partial reads */ 763 | if( i_ret != i_size ) 764 | { 765 | int i_seek; 766 | 767 | dvdcss->i_pos = -1; 768 | i_seek = stream_seek( dvdcss, i_ret_blocks ); 769 | if( i_seek < 0 ) 770 | { 771 | return i_seek; 772 | } 773 | 774 | /* We have to return now so that i_pos isn't clobbered */ 775 | return i_ret_blocks; 776 | } 777 | 778 | dvdcss->i_pos += i_ret_blocks; 779 | return i_ret_blocks; 780 | } 781 | 782 | #if defined( _WIN32 ) 783 | static int win2k_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks ) 784 | { 785 | DWORD i_bytes; 786 | 787 | if( !ReadFile( (HANDLE) dvdcss->i_fd, p_buffer, 788 | i_blocks * DVDCSS_BLOCK_SIZE, 789 | &i_bytes, NULL ) ) 790 | { 791 | dvdcss->i_pos = -1; 792 | return -1; 793 | } 794 | 795 | i_bytes /= DVDCSS_BLOCK_SIZE; 796 | dvdcss->i_pos += i_bytes; 797 | return i_bytes; 798 | } 799 | #endif /* defined( _WIN32 ) */ 800 | 801 | /***************************************************************************** 802 | * Readv commands. 803 | *****************************************************************************/ 804 | static int libc_readv ( dvdcss_t dvdcss, const struct iovec *p_iovec, 805 | int i_blocks ) 806 | { 807 | #if defined( _WIN32 ) 808 | int i_index, i_len, i_total = 0; 809 | unsigned char *p_base; 810 | int i_bytes; 811 | 812 | for( i_index = i_blocks; 813 | i_index; 814 | i_index--, p_iovec++ ) 815 | { 816 | i_len = p_iovec->iov_len; 817 | p_base = p_iovec->iov_base; 818 | 819 | if( i_len <= 0 ) 820 | { 821 | continue; 822 | } 823 | 824 | i_bytes = read( dvdcss->i_fd, p_base, i_len ); 825 | 826 | if( i_bytes < 0 ) 827 | { 828 | /* One of the reads failed, too bad. 829 | * We won't even bother returning the reads that went OK, 830 | * and as in the POSIX spec the file position is left 831 | * unspecified after a failure */ 832 | dvdcss->i_pos = -1; 833 | return -1; 834 | } 835 | 836 | i_total += i_bytes; 837 | i_total /= DVDCSS_BLOCK_SIZE; 838 | 839 | if( i_bytes != i_len ) 840 | { 841 | /* We reached the end of the file or a signal interrupted 842 | * the read. Return a partial read. */ 843 | int i_seek; 844 | 845 | dvdcss->i_pos = -1; 846 | i_seek = libc_seek( dvdcss, i_total ); 847 | if( i_seek < 0 ) 848 | { 849 | return i_seek; 850 | } 851 | 852 | /* We have to return now so that i_pos isn't clobbered */ 853 | return i_total; 854 | } 855 | } 856 | 857 | dvdcss->i_pos += i_total; 858 | return i_total; 859 | #else 860 | int i_read = readv( dvdcss->i_fd, p_iovec, i_blocks ); 861 | 862 | if( i_read < 0 ) 863 | { 864 | dvdcss->i_pos = -1; 865 | return i_read; 866 | } 867 | 868 | i_read /= DVDCSS_BLOCK_SIZE; 869 | dvdcss->i_pos += i_read; 870 | return i_read; 871 | #endif 872 | } 873 | 874 | /***************************************************************************** 875 | * stream_readv: vectored read 876 | *****************************************************************************/ 877 | static int stream_readv ( dvdcss_t dvdcss, const struct iovec *p_iovec, 878 | int i_blocks ) 879 | { 880 | int i_read; 881 | 882 | if( !dvdcss->p_stream_cb->pf_readv ) 883 | return -1; 884 | 885 | i_read = dvdcss->p_stream_cb->pf_readv( dvdcss->p_stream, p_iovec, 886 | i_blocks ); 887 | 888 | if( i_read < 0 ) 889 | { 890 | dvdcss->i_pos = -1; 891 | return i_read; 892 | } 893 | 894 | dvdcss->i_pos += i_read / DVDCSS_BLOCK_SIZE; 895 | return i_read / DVDCSS_BLOCK_SIZE; 896 | } 897 | 898 | #if defined( _WIN32 ) 899 | /***************************************************************************** 900 | * win2k_readv: vectored read using ReadFile for Win2K 901 | *****************************************************************************/ 902 | static int win2k_readv ( dvdcss_t dvdcss, const struct iovec *p_iovec, 903 | int i_blocks ) 904 | { 905 | int i_index; 906 | int i_blocks_read, i_blocks_total = 0; 907 | DWORD i_bytes; 908 | 909 | /* Check the size of the readv temp buffer, just in case we need to 910 | * realloc something bigger */ 911 | if( dvdcss->i_readv_buf_size < i_blocks * DVDCSS_BLOCK_SIZE ) 912 | { 913 | dvdcss->i_readv_buf_size = i_blocks * DVDCSS_BLOCK_SIZE; 914 | 915 | free( dvdcss->p_readv_buffer ); 916 | 917 | /* Allocate a buffer which will be used as a temporary storage 918 | * for readv */ 919 | dvdcss->p_readv_buffer = malloc( dvdcss->i_readv_buf_size ); 920 | if( !dvdcss->p_readv_buffer ) 921 | { 922 | print_error( dvdcss, "scatter input (readv) failed" ); 923 | dvdcss->i_pos = -1; 924 | return -1; 925 | } 926 | } 927 | 928 | for( i_index = i_blocks; i_index; i_index-- ) 929 | { 930 | i_blocks_total += p_iovec[i_index-1].iov_len; 931 | } 932 | 933 | if( i_blocks_total <= 0 ) return 0; 934 | 935 | if( !ReadFile( (HANDLE)dvdcss->i_fd, dvdcss->p_readv_buffer, 936 | i_blocks_total, &i_bytes, NULL ) ) 937 | { 938 | /* The read failed... too bad. 939 | * As in the POSIX spec the file position is left 940 | * unspecified after a failure */ 941 | dvdcss->i_pos = -1; 942 | return -1; 943 | } 944 | i_blocks_read = i_bytes / DVDCSS_BLOCK_SIZE; 945 | 946 | /* We just have to copy the content of the temp buffer into the iovecs */ 947 | for( i_index = 0, i_blocks_total = i_blocks_read; 948 | i_blocks_total > 0; 949 | i_index++ ) 950 | { 951 | memcpy( p_iovec[i_index].iov_base, 952 | dvdcss->p_readv_buffer + (i_blocks_read - i_blocks_total) 953 | * DVDCSS_BLOCK_SIZE, 954 | p_iovec[i_index].iov_len ); 955 | /* if we read less blocks than asked, we'll just end up copying 956 | * garbage, this isn't an issue as we return the number of 957 | * blocks actually read */ 958 | i_blocks_total -= ( p_iovec[i_index].iov_len / DVDCSS_BLOCK_SIZE ); 959 | } 960 | 961 | dvdcss->i_pos += i_blocks_read; 962 | return i_blocks_read; 963 | } 964 | #endif /* defined( _WIN32 ) */ 965 | --------------------------------------------------------------------------------