]> git.sesse.net Git - vlc/commitdiff
* fixes for the Qt plugin compilation under Debian
authorSam Hocevar <sam@videolan.org>
Mon, 2 Apr 2001 23:30:41 +0000 (23:30 +0000)
committerSam Hocevar <sam@videolan.org>
Mon, 2 Apr 2001 23:30:41 +0000 (23:30 +0000)
 * heavy butchering in the CSS and DVD ioctl code to put all architecture-
   dependent code in dvd_ioctl.c

 * added almost fully-functional /dev/dvd driver for MacOS X in
   extras/DVDioctl; to build it:

    % cd extras/DVDioctl
    % pbxbuild
    % kextload build/DVDioctl.kext # note: kextload has to be run as root

   be aware that the license for the DVDioctl kernel extension is
   not GPL but APSL, because I borrowed some code from the Darwin kernel.

15 files changed:
INSTALL
Makefile.in
extras/MacOSX_dvdioctl/DVDioctl.cpp [new file with mode: 0644]
extras/MacOSX_dvdioctl/DVDioctl.h [new file with mode: 0644]
extras/MacOSX_dvdioctl/DVDioctl.pbproj/project.pbxproj [new file with mode: 0644]
extras/MacOSX_dvdioctl/English.lproj/InfoPlist.strings [new file with mode: 0644]
include/config.h.in
include/defs.h.in
plugins/dvd/dvd_css.c
plugins/dvd/dvd_css.h
plugins/dvd/dvd_ioctl.c
plugins/dvd/dvd_ioctl.h
plugins/dvd/input_dvd.c
plugins/dvd/input_dvd.h
src/lpcm_decoder/lpcm_decoder_thread.c

diff --git a/INSTALL b/INSTALL
index a27e29d8d875baaa82bba9a78b909a7f4c4a13f9..12ba1d0c5975356382e6214d6b4efc61ad12f134 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -16,13 +16,14 @@ Here is a shortcut to copy-paste for a complete build:
 
    make distclean 2>/dev/null ; ./configure --prefix=/usr --enable-gnome \
       --enable-fb --with-glide --with-ggi --with-sdl --enable-esd \
-      --enable-alsa --enable-mga --enable-gtk --enable-qt && make
+      --enable-alsa --enable-mga --enable-gtk --enable-qt --enable-xvideo \
+   && make
 
 If you intend to debug stuff, you may want to disable optimizations:
 
    make distclean 2>/dev/null ; ./configure --prefix=/usr --enable-gnome \
       --enable-fb --with-glide --with-ggi --with-sdl --enable-esd \
-      --enable-alsa --enable-mga --enable-gtk --enable-qt \
+      --enable-alsa --enable-mga --enable-gtk --enable-qt --enable-xvideo \
       --disable-optimizatons && make
 
 
index 4b95240734baac78713ab0a529b0c643d0703a82..2c286860e3710474ba4d85deca0aee599226e0c8 100644 (file)
@@ -70,7 +70,7 @@ endif
 # C headers directories
 #
 INCLUDE += @INCLUDE@
-INCLUDE += -Iinclude -I/usr/local/include
+INCLUDE += -Iinclude -Iextras -I/usr/local/include
 
 #
 # Libraries
@@ -636,7 +636,7 @@ $(PLUGIN_GLIDE): %.o: %.c
 $(PLUGIN_QT): %.o: Makefile.dep
 $(PLUGIN_QT): %.o: .dep/%.dpp
 $(PLUGIN_QT): %.o: %.moc
-       $(CC) $(CFLAGS) $(PCFLAGS) -I${QTDIR}/include -c -o $@ $(<:%.moc=%.cpp)
+       $(CC) $(CFLAGS) $(PCFLAGS) -I/usr/include/qt -I${QTDIR}/include -c -o $@ $(<:%.moc=%.cpp)
 $(PLUGIN_QT:%.o=%.moc): %.moc: %.cpp
        moc -i $< -o $@
 
diff --git a/extras/MacOSX_dvdioctl/DVDioctl.cpp b/extras/MacOSX_dvdioctl/DVDioctl.cpp
new file mode 100644 (file)
index 0000000..9eb0aed
--- /dev/null
@@ -0,0 +1,601 @@
+/*****************************************************************************
+ * DVDioctl.cpp: Linux-like DVD driver for Darwin and MacOS X
+ *****************************************************************************
+ * Copyright (C) 1998-2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2001 VideoLAN
+ * $Id: DVDioctl.cpp,v 1.1 2001/04/02 23:30:41 sam Exp $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * TODO:
+ * - add a timeout to waitForService() so that we don't wait forever
+ * - find a way to prevent user from ejecting DVD using the GUI while
+ *   it is still in use
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+extern "C"
+{
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/syslog.h>
+#include <sys/systm.h>
+#include <sys/ioccom.h>
+#include <sys/fcntl.h>
+#include <sys/buf.h>
+#include <sys/uio.h>
+#include <miscfs/devfs/devfs.h>
+
+#include <mach/mach_types.h>
+}
+
+#include <IOKit/IOLib.h>
+#include <IOKit/IOService.h>
+#include <IOKit/storage/IODVDMedia.h>
+#include <IOKit/storage/IOMedia.h>
+
+#include "DVDioctl.h"
+
+/*****************************************************************************
+ * Driver class
+ *****************************************************************************/
+class DVDioctl : public IOService
+{
+    OSDeclareDefaultStructors( DVDioctl )
+
+public:
+
+    virtual bool       init   ( OSDictionary *dictionary = 0 );
+    virtual IOService *probe  ( IOService *provider, SInt32 *score );
+    virtual bool       start  ( IOService *provider );
+    virtual void       stop   ( IOService *provider );
+    virtual void       free   ( void );
+};
+
+#define super IOService
+OSDefineMetaClassAndStructors( DVDioctl, IOService )
+
+/*****************************************************************************
+ * Variable typedefs
+ *****************************************************************************/
+typedef void * dkr_t;
+typedef enum { DKRTYPE_BUF, DKRTYPE_DIO } dkrtype_t;
+typedef struct dio { dev_t dev; struct uio * uio; } dio_t;
+typedef struct buf buf_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  DVDClose    ( dev_t, int, int, struct proc * );
+static int  DVDIoctl    ( dev_t, u_long, caddr_t, int, struct proc * );
+static int  DVDOpen     ( dev_t, int, int, struct proc * );
+static int  DVDSize     ( dev_t );
+static void DVDStrategy ( buf_t * );
+static int  DVDReadWrite( dkr_t, dkrtype_t );
+static void DVDReadWriteCompletion( void *, void *, IOReturn, UInt64 );
+
+static struct bdevsw device_functions =
+{
+    DVDOpen, DVDClose, DVDStrategy, DVDIoctl, eno_dump, DVDSize, D_DISK
+};
+
+/*****************************************************************************
+ * Local variables
+ *****************************************************************************/
+static DVDioctl * p_this = NULL;
+
+static bool b_inuse;
+static int i_major;
+static void *p_node;
+static IODVDMedia *p_dvd;
+
+/*****************************************************************************
+ * DKR_GET_DEV: borrowed from IOMediaBSDClient.cpp
+ *****************************************************************************/
+static inline dev_t DKR_GET_DEV(dkr_t dkr, dkrtype_t dkrtype)
+{
+    return (dkrtype == DKRTYPE_BUF)
+           ? ((buf_t *)dkr)->b_dev : ((dio_t *)dkr)->dev;
+}
+
+/*****************************************************************************
+ * DKR_GET_BYTE_COUNT: borrowed from IOMediaBSDClient.cpp
+ *****************************************************************************/
+static inline UInt64 DKR_GET_BYTE_COUNT(dkr_t dkr, dkrtype_t dkrtype)
+{
+    return (dkrtype == DKRTYPE_BUF)
+           ? ((buf_t *)dkr)->b_bcount : ((dio_t *)dkr)->uio->uio_resid;
+}
+
+/*****************************************************************************
+ * DKR_GET_BYTE_START: borrowed from IOMediaBSDClient.cpp
+ *****************************************************************************/
+static inline UInt64 DKR_GET_BYTE_START(dkr_t dkr, dkrtype_t dkrtype)
+{
+    if (dkrtype == DKRTYPE_BUF)
+    {
+        buf_t * bp    = (buf_t *)dkr;
+        return bp->b_blkno * p_dvd->getPreferredBlockSize();
+    }
+    return ((dio_t *)dkr)->uio->uio_offset;
+}
+
+/*****************************************************************************
+ * DKR_IS_READ: borrowed from IOMediaBSDClient.cpp
+ *****************************************************************************/
+static inline bool DKR_IS_READ(dkr_t dkr, dkrtype_t dkrtype)
+{
+    return (dkrtype == DKRTYPE_BUF)
+           ? ((((buf_t *)dkr)->b_flags & B_READ) == B_READ)
+           : ((((dio_t *)dkr)->uio->uio_rw) == UIO_READ);
+}
+
+/*****************************************************************************
+ * DKR_IS_ASYNCHRONOUS: borrowed from IOMediaBSDClient.cpp
+ *****************************************************************************/
+static inline bool DKR_IS_ASYNCHRONOUS(dkr_t dkr, dkrtype_t dkrtype)
+{
+    return (dkrtype == DKRTYPE_BUF) ? true : false;
+}
+
+/*****************************************************************************
+ * DKR_IS_RAW: borrowed from IOMediaBSDClient.cpp
+ *****************************************************************************/
+static inline bool DKR_IS_RAW(dkr_t dkr, dkrtype_t dkrtype)
+{
+    return (dkrtype == DKRTYPE_BUF) ? false : true;
+}
+
+/*****************************************************************************
+ * DKR_SET_BYTE_COUNT: borrowed from IOMediaBSDClient.cpp
+ *****************************************************************************/
+static inline void DKR_SET_BYTE_COUNT(dkr_t dkr, dkrtype_t dkrtype, UInt64 bcount)
+{
+    if (dkrtype == DKRTYPE_BUF)
+    {
+        ((buf_t *)dkr)->b_resid = ((buf_t *)dkr)->b_bcount - bcount;
+    }
+    else
+    {
+        ((dio_t *)dkr)->uio->uio_resid -= bcount;
+    }
+}
+
+/*****************************************************************************
+ * DKR_RUN_COMPLETION: borrowed from IOMediaBSDClient.cpp
+ *****************************************************************************/
+static inline void DKR_RUN_COMPLETION(dkr_t dkr, dkrtype_t dkrtype, IOReturn status)
+{
+    if (dkrtype == DKRTYPE_BUF)
+    {
+        buf_t * bp = (buf_t *)dkr;
+
+        bp->b_error  = p_this->errnoFromReturn(status);
+        bp->b_flags |= (status != kIOReturnSuccess) ? B_ERROR : 0;
+        biodone(bp);
+    }
+}
+
+/*****************************************************************************
+ * DKR_GET_BUFFER: borrowed from IOMediaBSDClient.cpp
+ *****************************************************************************/
+static inline IOMemoryDescriptor * DKR_GET_BUFFER(dkr_t dkr, dkrtype_t dkrtype)
+{
+    if (dkrtype == DKRTYPE_BUF)
+    {
+        buf_t * bp = (buf_t *)dkr;
+
+        if ( (bp->b_flags & B_VECTORLIST) )
+        {
+            assert(sizeof(IOPhysicalRange         ) == sizeof(iovec          ));
+            assert(sizeof(IOPhysicalRange::address) == sizeof(iovec::iov_base));
+            assert(sizeof(IOPhysicalRange::length ) == sizeof(iovec::iov_len ));
+            return IOMemoryDescriptor::withPhysicalRanges(
+              (IOPhysicalRange *) bp->b_vectorlist,
+              (UInt32)            bp->b_vectorcount,
+              (bp->b_flags & B_READ) ? kIODirectionIn : kIODirectionOut,
+              true );
+        }
+
+        return IOMemoryDescriptor::withAddress(
+          (vm_address_t) bp->b_data,
+          (vm_size_t)    bp->b_bcount,
+          (bp->b_flags & B_READ) ? kIODirectionIn : kIODirectionOut,
+          (bp->b_flags & B_PHYS) ? current_task() : kernel_task );
+    }
+    else
+    {
+        struct uio * uio = ((dio_t *)dkr)->uio;
+
+        assert(sizeof(IOVirtualRange         ) == sizeof(iovec          ));
+        assert(sizeof(IOVirtualRange::address) == sizeof(iovec::iov_base));
+        assert(sizeof(IOVirtualRange::length ) == sizeof(iovec::iov_len ));
+
+        return IOMemoryDescriptor::withRanges(
+        (IOVirtualRange *) uio->uio_iov,
+        (UInt32)           uio->uio_iovcnt,
+        (uio->uio_rw     == UIO_READ    ) ? kIODirectionIn : kIODirectionOut,
+        (uio->uio_segflg != UIO_SYSSPACE) ? current_task() : kernel_task,
+        true );
+    }
+}
+
+/*****************************************************************************
+ * DVDioctl::init: initialize the driver structure
+ *****************************************************************************/
+bool DVDioctl::init( OSDictionary *p_dict = 0 )
+{
+    //IOLog( "DVD ioctl: initializing\n" );
+
+    p_this = this;
+
+    p_node  = NULL;
+    p_dvd   = NULL;
+    i_major = -1;
+    b_inuse = false;
+
+    bool res = super::init( p_dict );
+
+    return res;
+}
+    
+/*****************************************************************************
+ * DVDioctl::probe: check whether the driver can be safely activated
+ *****************************************************************************/
+IOService * DVDioctl::probe( IOService *provider, SInt32 *score )
+{
+    //IOLog( "DVD ioctl: probing\n" );
+    IOService * res = super::probe( provider, score );
+
+    return res;
+}
+
+/*****************************************************************************
+ * DVDioctl::start: start the driver
+ *****************************************************************************/
+bool DVDioctl::start( IOService *provider )
+{
+    //IOLog( "DVD ioctl: starting\n" );
+
+    if( !super::start( provider ) )
+    {
+        return false;
+    }
+
+    //IOLog( "DVD ioctl: creating device\n" );
+
+    i_major = bdevsw_add( -1, &device_functions );
+
+    if( i_major == -1 )
+    {
+        //log(LOG_INFO, "DVD ioctl: failed to allocate a major number\n");
+        return false;
+    }
+
+    p_node = devfs_make_node ( makedev( i_major, 0 ), DEVFS_BLOCK,
+                               UID_ROOT, GID_WHEEL, 0666, "dvd" );
+
+    if( p_node == NULL )
+    {
+        //log( LOG_INFO, "DVD ioctl: failed creating node\n" );
+
+        if( bdevsw_remove(i_major, &device_functions) == -1 )
+        {
+            //log( LOG_INFO, "DVD ioctl: bdevsw_remove failed\n" );
+        }
+
+        return false;
+    }
+
+    return true;
+}
+
+/*****************************************************************************
+ * DVDioctl::stop: stop the driver
+ *****************************************************************************/
+void DVDioctl::stop( IOService *provider )
+{
+    //IOLog( "DVD ioctl: removing device\n" );
+
+    if( p_node != NULL )
+    {
+        devfs_remove( p_node );
+    }
+
+    if( i_major != -1 )
+    {
+        if( bdevsw_remove(i_major, &device_functions) == -1 )
+        {
+            //log( LOG_INFO, "DVD ioctl: bdevsw_remove failed\n" );
+        }
+    }
+
+    //IOLog( "DVD ioctl: stopping\n" );
+    super::stop( provider );
+}
+  
+/*****************************************************************************
+ * DVDioctl::free: free all resources allocated by the driver
+ *****************************************************************************/
+void DVDioctl::free( void )
+{
+    //IOLog( "DVD ioctl: freeing\n" );
+    super::free( );
+}
+
+#if 0
+IOReturn DVDioctl::report( IODVDMedia *DVD, IOMemoryDescriptor *buffer, const DVDKeyClass keyClass, const UInt32 lba, const UInt8 agid, const DVDKeyFormat keyFormat )
+{
+    IOLog( "DVD ioctl: reportkey\n" );
+    return DVD->getProvider()->reportKey( buffer, keyClass, lba, agid, keyFormat );
+}
+
+IOReturn DVDioctl::send( IODVDMedia *DVD, IOMemoryDescriptor *buffer, const DVDKeyClass keyClass, const UInt32 lba, const DVDKeyFormat keyFormat )
+{
+    IOLog( "DVD ioctl: sendkey\n" );
+    return DVD->getProvider()->sendKey( buffer, keyClass, lba, keyFormat );
+}
+#endif
+
+/* following functions are local */
+
+/*****************************************************************************
+ * DVDOpen: look for an IODVDMedia object and open it
+ *****************************************************************************/
+static int DVDOpen( dev_t dev, int flags, int devtype, struct proc * )
+{
+    IOStorageAccess level;
+    int i_err;
+
+    /* Check that the device hasn't already been opened */
+    if( b_inuse )
+    {
+        //log( LOG_INFO, "DVD ioctl: already opened\n" );
+        return EBUSY;
+    }
+    else
+    {
+        b_inuse = true;
+    }
+
+    IOService * p_root = IOService::getServiceRoot();
+   
+    if( p_root == NULL )
+    {
+        //log( LOG_INFO, "DVD ioctl: couldn't find root\n" );
+        b_inuse = false;
+        return ENXIO;
+    }
+
+    OSDictionary * p_dict = p_root->serviceMatching( kIODVDMediaClass );
+
+    if( p_dict == NULL )
+    {
+        //log( LOG_INFO, "DVD ioctl: couldn't find dictionary\n" );
+        b_inuse = false;
+        return ENXIO;
+    }
+
+    p_dvd = OSDynamicCast( IODVDMedia, p_root->waitForService( p_dict ) );
+
+    if( p_dvd == NULL )
+    {
+        //log( LOG_INFO, "DVD ioctl: couldn't find service\n" );
+        b_inuse = false;
+        return ENXIO;
+    }
+
+    //log( LOG_INFO, "DVD ioctl: found DVD\n" );
+
+    level = (flags & FWRITE) ? kIOStorageAccessReaderWriter
+                             : kIOStorageAccessReader;
+
+    if( p_dvd->open( p_this, 0, level) )
+    {
+        log( LOG_INFO, "DVD ioctl: IODVDMedia->open()\n" );
+        i_err = 0;
+    }
+    else
+    {
+        log( LOG_INFO, "DVD ioctl: IODVDMedia object busy\n" );
+        b_inuse = false;
+        i_err = EBUSY;
+    }
+
+    return i_err;
+}
+
+/*****************************************************************************
+ * DVDClose: close the IODVDMedia object
+ *****************************************************************************/
+static int DVDClose( dev_t dev, int flags, int devtype, struct proc * )
+{
+    /* Release the device */
+    p_dvd->close( p_this );
+    b_inuse = false;
+
+    log( LOG_INFO, "DVD ioctl: IODVDMedia->close()\n" );
+
+    return 0;
+}
+
+/*****************************************************************************
+ * DVDSize: return the device size
+ *****************************************************************************/
+static int DVDSize( dev_t dev )
+{
+    return p_dvd->getPreferredBlockSize();
+}
+
+/*****************************************************************************
+ * DVDStrategy: perform read or write operations
+ *****************************************************************************/
+static void DVDStrategy( buf_t * bp )
+{
+    DVDReadWrite(bp, DKRTYPE_BUF);
+    return;
+}
+
+/*****************************************************************************
+ * DVDIoctl: issue an ioctl on the device
+ *****************************************************************************/
+static int DVDIoctl( dev_t dev, u_long cmd, caddr_t addr, int flags,
+                     struct proc *p )
+{
+    switch( cmd )
+    {
+        case IODVD_READ_STRUCTURE:
+            //log( LOG_INFO, "DVD ioctl: IODVD_READ_STRUCTURE\n" );
+            return 0;
+
+        case IODVD_SEND_KEY:
+            //log( LOG_INFO, "DVD ioctl: IODVD_SEND_KEY\n" );
+            return 0;
+
+        case IODVD_REPORT_KEY:
+            //log( LOG_INFO, "DVD ioctl: IODVD_REPORT_KEY\n" );
+            return 0;
+
+        default:
+            //log( LOG_INFO, "DVD ioctl: unknown ioctl\n" );
+            return EINVAL;
+    }
+}
+
+/*****************************************************************************
+ * DVDReadWrite: borrowed from IOMediaBSDClient.cpp
+ *****************************************************************************/
+static int DVDReadWrite(dkr_t dkr, dkrtype_t dkrtype)
+{
+    IOMemoryDescriptor * buffer;
+    register UInt64      byteCount;
+    register UInt64      byteStart;
+    UInt64               mediaSize;
+    IOReturn             status;
+
+    byteCount = DKR_GET_BYTE_COUNT(dkr, dkrtype);
+    byteStart = DKR_GET_BYTE_START(dkr, dkrtype);
+    mediaSize = p_dvd->getSize();
+
+    if ( byteStart >= mediaSize )
+    {
+        status = DKR_IS_READ(dkr,dkrtype) ? kIOReturnSuccess : kIOReturnIOError;        goto dkreadwriteErr;
+    }
+
+    if ( DKR_IS_RAW(dkr, dkrtype) )
+    {
+        UInt64 mediaBlockSize = p_dvd->getPreferredBlockSize();
+
+        if ( (byteStart % mediaBlockSize) || (byteCount % mediaBlockSize) )
+        {
+            status = kIOReturnNotAligned;
+            goto dkreadwriteErr;
+        }
+    }
+
+    buffer = DKR_GET_BUFFER(dkr, dkrtype);
+
+    if ( buffer == 0 )
+    {
+        status = kIOReturnNoMemory;
+        goto dkreadwriteErr;
+    }
+
+    if ( byteCount > mediaSize - byteStart )
+    {
+        IOMemoryDescriptor * originalBuffer = buffer;
+
+        buffer = IOMemoryDescriptor::withSubRange( originalBuffer, 0,
+                     mediaSize - byteStart, originalBuffer->getDirection() );
+        originalBuffer->release();
+        if ( buffer == 0 )
+        {
+            status = kIOReturnNoMemory;
+            goto dkreadwriteErr;
+        }
+    }
+
+    if ( DKR_IS_ASYNCHRONOUS(dkr, dkrtype) )
+    {
+        IOStorageCompletion completion;
+
+        completion.target    = dkr;
+        completion.action    = DVDReadWriteCompletion;
+        completion.parameter = (void *) dkrtype;
+
+        if ( DKR_IS_READ(dkr, dkrtype) )
+        {
+            p_dvd->read(  p_this, byteStart, buffer, completion );
+        }
+        else
+        {
+            p_dvd->write( p_this, byteStart, buffer, completion );
+        }
+
+        status = kIOReturnSuccess;
+    }
+    else
+    {
+        if ( DKR_IS_READ(dkr, dkrtype) )
+        {
+            status = p_dvd->IOStorage::read( p_this, byteStart,
+                                             buffer, &byteCount );
+        }
+        else
+        {
+            status = p_dvd->IOStorage::write( p_this, byteStart,
+                                              buffer, &byteCount );
+        }
+
+        DVDReadWriteCompletion(dkr, (void *)dkrtype, status, byteCount);
+    }
+
+    buffer->release();
+    return p_this->errnoFromReturn(status);
+dkreadwriteErr:
+
+    DVDReadWriteCompletion(dkr, (void *)dkrtype, status, 0);
+
+    return p_this->errnoFromReturn(status);
+}
+
+/*****************************************************************************
+ * DVDReadWriteCompletion: borrowed from IOMediaBSDClient.cpp
+ *****************************************************************************/
+static void DVDReadWriteCompletion( void *   target,
+                                    void *   parameter,
+                                    IOReturn status,
+                                    UInt64   actualByteCount )
+{
+    dkr_t     dkr      = (dkr_t) target;
+    dkrtype_t dkrtype  = (dkrtype_t) (int) parameter;
+    dev_t     dev      = DKR_GET_DEV(dkr, dkrtype);
+
+    if ( status != kIOReturnSuccess )
+    {
+        IOLog( "%s: %s.\n", /*p_this->name*/ "DVD ioctl",
+               p_this->stringFromReturn(status) );
+    }
+
+    DKR_SET_BYTE_COUNT(dkr, dkrtype, actualByteCount);
+    DKR_RUN_COMPLETION(dkr, dkrtype, status);
+}
+
diff --git a/extras/MacOSX_dvdioctl/DVDioctl.h b/extras/MacOSX_dvdioctl/DVDioctl.h
new file mode 100644 (file)
index 0000000..dd9e73e
--- /dev/null
@@ -0,0 +1,28 @@
+/*****************************************************************************
+ * DVDioctl.h: Linux-like DVD driver for Darwin and MacOS X
+ *****************************************************************************
+ * Copyright (C) 2001 VideoLAN
+ * $Id: DVDioctl.h,v 1.1 2001/04/02 23:30:41 sam Exp $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *****************************************************************************/
+
+struct sum { int a, b, r; };
+#define IODVD_READ_STRUCTURE _IOWR('B', 1, struct sum)
+#define IODVD_SEND_KEY       _IOWR('B', 2, struct sum)
+#define IODVD_REPORT_KEY     _IOWR('B', 3, struct sum)
+
diff --git a/extras/MacOSX_dvdioctl/DVDioctl.pbproj/project.pbxproj b/extras/MacOSX_dvdioctl/DVDioctl.pbproj/project.pbxproj
new file mode 100644 (file)
index 0000000..3b737b4
--- /dev/null
@@ -0,0 +1,274 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 32;
+       objects = {
+               06AA1264FFB2107B11CA28AA = {
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       generatedFileNames = (
+                       );
+                       isa = PBXShellScriptBuildPhase;
+                       name = "Shell Script";
+                       neededFileNames = (
+                       );
+                       shellPath = /bin/sh;
+                       shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPostprocess\";\nif [ -x \"$script\" ]; then\n    . \"$script\"\nfi";
+               };
+               06AA1265FFB2107B11CA28AA = {
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                       };
+                       isa = PBXBuildStyle;
+                       name = Development;
+               };
+               06AA1266FFB2107B11CA28AA = {
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                       };
+                       isa = PBXBuildStyle;
+                       name = Deployment;
+               };
+               06AA1267FFB2110C11CA28AA = {
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       generatedFileNames = (
+                       );
+                       isa = PBXShellScriptBuildPhase;
+                       name = "Shell Script";
+                       neededFileNames = (
+                       );
+                       shellPath = /bin/sh;
+                       shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPreprocess\";\nif [ -x \"$script\" ]; then\n    . \"$script\"\nfi";
+               };
+               089C1669FE841209C02AAC07 = {
+                       buildStyles = (
+                               06AA1265FFB2107B11CA28AA,
+                               06AA1266FFB2107B11CA28AA,
+                       );
+                       isa = PBXProject;
+                       mainGroup = 089C166AFE841209C02AAC07;
+                       projectDirPath = .;
+                       targets = (
+                               089C1673FE841209C02AAC07,
+                       );
+               };
+               089C166AFE841209C02AAC07 = {
+                       children = (
+                               247142CAFF3F8F9811CA285C,
+                               089C167CFE841241C02AAC07,
+                               19C28FB6FE9D52B211CA2CBB,
+                       );
+                       isa = PBXGroup;
+                       name = DVDioctl;
+                       refType = 4;
+               };
+               089C1673FE841209C02AAC07 = {
+                       buildPhases = (
+                               06AA1267FFB2110C11CA28AA,
+                               089C1674FE841209C02AAC07,
+                               089C1675FE841209C02AAC07,
+                               089C1676FE841209C02AAC07,
+                               089C1677FE841209C02AAC07,
+                               089C1679FE841209C02AAC07,
+                               06AA1264FFB2107B11CA28AA,
+                       );
+                       buildSettings = {
+                               FRAMEWORK_SEARCH_PATHS = "";
+                               HEADER_SEARCH_PATHS = "";
+                               INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions";
+                               KERNEL_MODULE = YES;
+                               LIBRARY_SEARCH_PATHS = "";
+                               MODULE_IOKIT = YES;
+                               MODULE_NAME = DVDioctl;
+                               MODULE_VERSION = 1.0.0d1;
+                               OPTIMIZATION_CFLAGS = "";
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = DVDioctl;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+                               WRAPPER_EXTENSION = kext;
+                       };
+                       conditionalBuildSettings = {
+                       };
+                       dependencies = (
+                       );
+                       isa = PBXBundleTarget;
+                       name = DVDioctl;
+                       productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions";
+                       productName = DVDioctl;
+                       productReference = 0B81C263FFB7832611CA28AA;
+                       productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
+<plist version=\"0.9\">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>DVDioctl</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>DVDioctl</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundlePackageType</key>
+       <string>KEXT</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.0.0d1</string>
+       <key>IOKitPersonalities</key>
+       <dict>
+               <key>DVDioctl</key>
+               <dict>
+                       <key>CFBundleIdentifier</key>
+                       <string>DVDioctl</string>
+                       <key>IOClass</key>
+                       <string>DVDioctl</string>
+                       <key>IOKitDebug</key>
+                       <integer>65535</integer>
+                       <key>IOMatchCategory</key>
+                       <string>DVDioctl</string>
+                       <key>IOProviderClass</key>
+                       <string>IOResources</string>
+                       <key>IOResourceMatch</key>
+                       <string>IOKit</string>
+               </dict>
+       </dict>
+       <key>OSBundleLibraries</key>
+       <dict/>
+</dict>
+</plist>
+";
+                       shouldUseHeadermap = 1;
+               };
+               089C1674FE841209C02AAC07 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               1A224C40FF42367911CA2CB7,
+                       );
+                       isa = PBXHeadersBuildPhase;
+                       name = Headers;
+               };
+               089C1675FE841209C02AAC07 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               089C1680FE841241C02AAC07,
+                       );
+                       isa = PBXResourcesBuildPhase;
+                       name = "Bundle Resources";
+               };
+               089C1676FE841209C02AAC07 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               1A224C41FF42367911CA2CB7,
+                       );
+                       isa = PBXSourcesBuildPhase;
+                       name = Sources;
+               };
+               089C1677FE841209C02AAC07 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       isa = PBXFrameworksBuildPhase;
+                       name = "Frameworks & Libraries";
+               };
+               089C1679FE841209C02AAC07 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       isa = PBXRezBuildPhase;
+                       name = "ResourceManager Resources";
+               };
+               089C167CFE841241C02AAC07 = {
+                       children = (
+                               089C167DFE841241C02AAC07,
+                       );
+                       isa = PBXGroup;
+                       name = Resources;
+                       refType = 4;
+               };
+               089C167DFE841241C02AAC07 = {
+                       children = (
+                               089C167EFE841241C02AAC07,
+                       );
+                       isa = PBXVariantGroup;
+                       name = InfoPlist.strings;
+                       refType = 4;
+               };
+               089C167EFE841241C02AAC07 = {
+                       fileEncoding = 10;
+                       isa = PBXFileReference;
+                       name = English;
+                       path = English.lproj/InfoPlist.strings;
+                       refType = 4;
+               };
+               089C1680FE841241C02AAC07 = {
+                       fileRef = 089C167DFE841241C02AAC07;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               0B81C263FFB7832611CA28AA = {
+                       isa = PBXBundleReference;
+                       path = DVDioctl.kext;
+                       refType = 3;
+               };
+               19C28FB6FE9D52B211CA2CBB = {
+                       children = (
+                               0B81C263FFB7832611CA28AA,
+                       );
+                       isa = PBXGroup;
+                       name = Products;
+                       refType = 4;
+               };
+               1A224C3EFF42367911CA2CB7 = {
+                       isa = PBXFileReference;
+                       path = DVDioctl.h;
+                       refType = 4;
+               };
+               1A224C3FFF42367911CA2CB7 = {
+                       isa = PBXFileReference;
+                       path = DVDioctl.cpp;
+                       refType = 4;
+               };
+               1A224C40FF42367911CA2CB7 = {
+                       fileRef = 1A224C3EFF42367911CA2CB7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               1A224C41FF42367911CA2CB7 = {
+                       fileRef = 1A224C3FFF42367911CA2CB7;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                               );
+                       };
+               };
+               247142CAFF3F8F9811CA285C = {
+                       children = (
+                               1A224C3EFF42367911CA2CB7,
+                               1A224C3FFF42367911CA2CB7,
+                       );
+                       isa = PBXGroup;
+                       name = Source;
+                       path = "";
+                       refType = 4;
+               };
+       };
+       rootObject = 089C1669FE841209C02AAC07;
+}
diff --git a/extras/MacOSX_dvdioctl/English.lproj/InfoPlist.strings b/extras/MacOSX_dvdioctl/English.lproj/InfoPlist.strings
new file mode 100644 (file)
index 0000000..42ccc05
Binary files /dev/null and b/extras/MacOSX_dvdioctl/English.lproj/InfoPlist.strings differ
index 1ecbb0e53240e70551d73028c4b314fc717e446e..77fd91fa3fa2a45167e69cc04c914dc96ee8fbbe 100644 (file)
@@ -78,7 +78,7 @@
  * in the Makefile */
 
 /* Modules specific debugging - this will produce a lot of output, but can be
- * usefull to track a bug */
+ * useful to track a bug */
 //#define DEBUG_INTF
 //#define DEBUG_INPUT
 //#define DEBUG_AUDIO
 #define INTF_WARNING_VAR                "warning_level"
 #define INTF_WARNING_DEFAULT            12
 
-/* Define to enable messages queues - disabling messages queue can be usefull
- * when debugging, since it allows messages which would not otherwise be printed,
- * due to a crash, to be printed anyway */
+/* Define to enable messages queues - disabling messages queue can be useful
+ * when debugging, since it allows messages which would not be printed
+ * due to a crash to be printed anyway */
 #ifndef DEBUG
 #define INTF_MSG_QUEUE
 #endif
index b3f89e83b6f416e0e5f0645f1fc0696eb7097cb3..90aaf9dc9776a32e0c0931bec5867d3eeeedbddd 100644 (file)
@@ -52,6 +52,9 @@
 /* Define if you have the vasprintf function.  */
 #undef HAVE_VASPRINTF
 
+/* Define if you have the <CoreAudio/AudioHardware.h> header file.  */
+#undef HAVE_COREAUDIO_AUDIOHARDWARE_H
+
 /* Define if you have the <SDL/SDL.h> header file.  */
 #undef HAVE_SDL_SDL_H
 
index 9e01c23afcc0c63172942201cb97b0cd5a606827..e3fe4221c5d6981861e22e97acd88107bdf79732 100644 (file)
@@ -2,7 +2,7 @@
  * dvd_css.c: Functions for DVD authentification and unscrambling
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_css.c,v 1.18 2001/03/03 11:01:07 sam Exp $
+ * $Id: dvd_css.c,v 1.19 2001/04/02 23:30:41 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#ifdef HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_DVDIO_H
-# include <sys/dvdio.h>
-#endif
-#ifdef LINUX_DVD
-# include <linux/cdrom.h>
-#endif
 
 #include "common.h"
 
@@ -67,7 +56,7 @@
  * Local prototypes
  *****************************************************************************/
 #ifdef HAVE_CSS
-static int  CSSGetASF    ( int i_fd );
+static int  CSSGetASF    ( css_t *p_css );
 static void CSSCryptKey  ( int i_key_type, int i_varient,
                            u8 const * pi_challenge, u8* pi_key );
 static int  CSSCracker   ( int i_start, unsigned char * p_crypted,
@@ -80,18 +69,16 @@ static int  CSSCracker   ( int i_start, unsigned char * p_crypted,
  *****************************************************************************/
 int CSSTest( int i_fd )
 {
-    dvd_struct dvd;
+    int i_ret, i_copyright;
 
-    dvd.type = DVD_STRUCT_COPYRIGHT;
-    dvd.copyright.layer_num = 0;
+    i_ret = dvd_ReadCopyright( i_fd, 0 /* i_layer */, &i_copyright );
 
-    if( dvd_ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 )
+    if( i_ret < 0 )
     {
-        intf_ErrMsg( "css error: DVD ioctl failed" );
-        return -1;
+        return i_ret;
     }
 
-    return dvd.copyright.cpst;
+    return i_copyright;
 }
 
 /*****************************************************************************
@@ -101,65 +88,53 @@ int CSSTest( int i_fd )
  * Since we don't need the disc key to find the title key, we just run the
  * basic unavoidable commands to authenticate device and disc.
  *****************************************************************************/
-css_t * CSSInit( int i_fd )
+int CSSInit( css_t * p_css )
 {
 #ifdef HAVE_CSS
     /* structures defined in cdrom.h or dvdio.h */
-    dvd_struct      dvd;
-    dvd_authinfo    auth_info;
-    css_t *         p_css;
+    char p_buffer[2048 + 4 + 1];
+    int  i_ret = -1;
+    int  i;
 
-    int             i_error = -1;
-    int             i;
+    p_css->i_agid = 0;
 
-    p_css = malloc( sizeof(css_t) );
-    if( p_css == NULL )
+    /* Test authentication success */
+    switch( CSSGetASF( p_css ) )
     {
-        return NULL;
-    }
-
-    p_css->i_fd = i_fd;
+        case -1:
+            return -1;
 
-    memset( &auth_info, 0, sizeof(auth_info) );
+        case 1:
+            return 0;
 
-    /* Test authentication success */
-    switch( CSSGetASF( i_fd ) )
-    {
-    case -1:
-        free( p_css );
-        return NULL;
-    case 1:
-        return p_css;
-    case 0:
-        intf_WarnMsg( 3, "css info: authenticating" );
+        case 0:
+            intf_WarnMsg( 3, "css info: authenticating" );
     }
 
     /* Init sequence, request AGID */
     for( i = 1; i < 4 ; ++i )
     {
-        intf_WarnMsg( 3, "css info: request AGID %d", i );
-        auth_info.type = DVD_LU_SEND_AGID;
-        auth_info.lsa.agid = 0;
-        i_error =  dvd_ioctl( i_fd, DVD_AUTH, &auth_info );
-        if( i_error != -1 )
+        intf_WarnMsg( 3, "css info: requesting AGID %d", i );
+
+        i_ret = dvd_LUSendAgid( p_css );
+
+        if( i_ret != -1 )
         {
-            /* No error during ioctl: we know if device
-             * is authenticated */
+            /* No error during ioctl: we know the device is authenticated */
             break;
         }
 
         intf_ErrMsg( "css error: AGID N/A, invalidating" );
-        auth_info.type = DVD_INVALIDATE_AGID;
-        auth_info.lsa.agid = 0;
-        dvd_ioctl( i_fd, DVD_AUTH, &auth_info );
+
+        p_css->i_agid = 0;
+        dvd_InvalidateAgid( p_css );
     }
 
     /* Unable to authenticate without AGID */
-    if( i_error == -1 )
+    if( i_ret == -1 )
     {
         intf_ErrMsg( "css error: could not get AGID" );
-        free( p_css );
-        return NULL;
+        return -1;
     }
 
     for( i = 0 ; i < 10; ++i )
@@ -167,37 +142,30 @@ css_t * CSSInit( int i_fd )
         p_css->disc.pi_challenge[i] = i;
     }
 
-    /* Send AGID to host */
-    auth_info.type = DVD_HOST_SEND_CHALLENGE;
-
     /* Get challenge from host */
     for( i = 0 ; i < 10 ; ++i )
     {
-        auth_info.hsc.chal[9-i] = p_css->disc.pi_challenge[i];
+        p_buffer[9-i] = p_css->disc.pi_challenge[i];
     }
-    /* Returning data, let LU change state */
-    p_css->i_agid = auth_info.lsa.agid;
 
     /* Send challenge to LU */
-    if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info )<0 )
+    if( dvd_HostSendChallenge( p_css, p_buffer ) < 0 )
     {
         intf_ErrMsg( "css error: failed sending challenge to LU" );
-        free( p_css );
-        return NULL;
+        return -1;
     }
 
     /* Get key1 from LU */
-    if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0)
+    if( dvd_LUSendKey1( p_css, p_buffer ) < 0)
     {
         intf_ErrMsg( "css error: failed getting key1 from LU" );
-        free( p_css );
-        return NULL;
+        return -1;
     }
 
     /* Send key1 to host */
     for( i = 0 ; i < KEY_SIZE ; i++ )
     {
-        p_css->disc.pi_key1[i] = auth_info.lsk.key[4-i];
+        p_css->disc.pi_key1[i] = p_buffer[4-i];
     }
 
     for( i = 0 ; i < 32 ; ++i )
@@ -210,7 +178,6 @@ css_t * CSSInit( int i_fd )
         {
             intf_WarnMsg( 3, "css info: drive authentic, using variant %d", i);
             p_css->disc.i_varient = i;
-            auth_info.type = DVD_LU_SEND_CHALLENGE;
             break;
         }
     }
@@ -218,117 +185,97 @@ css_t * CSSInit( int i_fd )
     if( i == 32 )
     {
         intf_ErrMsg( "css error: drive would not authenticate" );
-        auth_info.type = DVD_AUTH_FAILURE;
-        free( p_css );
-        return NULL;
+        return -1;
     }
 
     /* Get challenge from LU */
-    if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 )
+    if( dvd_LUSendChallenge( p_css, p_buffer ) < 0 )
     {
         intf_ErrMsg( "css error: failed getting challenge from LU" );
-        free( p_css );
-        return NULL;
+        return -1;
     }
 
     /* Send challenge to host */
     for( i = 0 ; i < 10 ; ++i )
     {
-        p_css->disc.pi_challenge[i] = auth_info.hsc.chal[9-i];
+        p_css->disc.pi_challenge[i] = p_buffer[9-i];
     }
 
     CSSCryptKey( 1, p_css->disc.i_varient, p_css->disc.pi_challenge,
-                                                    p_css->disc.pi_key2 );
-    auth_info.type = DVD_HOST_SEND_KEY2;
+                                               p_css->disc.pi_key2 );
 
     /* Get key2 from host */
     for( i = 0 ; i < KEY_SIZE ; ++i )
     {
-        auth_info.hsk.key[4-i] = p_css->disc.pi_key2[i];
+        p_buffer[4-i] = p_css->disc.pi_key2[i];
     }
-    /* Returning data, let LU change state */
 
     /* Send key2 to LU */
-    if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 )
+    if( dvd_HostSendKey2( p_css, p_buffer ) < 0 )
     {
-        intf_ErrMsg( "css error: failed sending key2 to LU (expected)" );
-        free( p_css );
-        return NULL;
+        intf_ErrMsg( "css error: failed sending key2 to LU" );
+        return -1;
     }
 
-    if( auth_info.type == DVD_AUTH_ESTABLISHED )
-    {
-        intf_WarnMsg( 3, "css info: authentication established" );
-    }
-    else if( auth_info.type == DVD_AUTH_FAILURE )
-    {
-        intf_ErrMsg( "css error: DVD authentication failed" );
-        free( p_css );
-        return NULL;
-    }
+    intf_WarnMsg( 3, "css info: authentication established" );
 
     memcpy( p_css->disc.pi_challenge, p_css->disc.pi_key1, KEY_SIZE );
     memcpy( p_css->disc.pi_challenge+KEY_SIZE, p_css->disc.pi_key2, KEY_SIZE );
-    CSSCryptKey( 2, p_css->disc.i_varient,
-                    p_css->disc.pi_challenge,
-                    p_css->disc.pi_key_check );
+    CSSCryptKey( 2, p_css->disc.i_varient, p_css->disc.pi_challenge,
+                                               p_css->disc.pi_key_check );
 
     intf_WarnMsg( 1, "css info: received Session Key" );
 
     if( p_css->i_agid < 0 )
     {
-        free( p_css );
-        return NULL;
+        return -1;
     }
 
     /* Test authentication success */
-    switch( CSSGetASF( i_fd ) )
+    switch( CSSGetASF( p_css ) )
     {
-    case -1:
-        free( p_css );
-        return NULL;
-    case 1:
-        return p_css;
-    case 0:
-        intf_WarnMsg( 3, "css info: getting disc key" );
+        case -1:
+            return -1;
+
+        case 1:
+            return 0;
+
+        case 0:
+            intf_WarnMsg( 3, "css info: getting disc key" );
     }
 
     /* Get encrypted disc key */
-    dvd.type = DVD_STRUCT_DISCKEY;
-    dvd.disckey.agid = p_css->i_agid;
-    memset( dvd.disckey.value, 0, 2048 );
-
-    if( dvd_ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 )
+    if( dvd_ReadKey( p_css, p_buffer ) < 0 )
     {
         intf_ErrMsg( "css error: could not read Disc Key" );
-        free( p_css );
-        return NULL;
+        return -1;
     }
-#if 1
+
     /* Unencrypt disc key using bus key */
-    for( i = 0 ; i < sizeof(dvd.disckey.value) ; i++ )
+    for( i = 0 ; i < 2048 ; i++ )
     {
-        dvd.disckey.value[i] ^= p_css->disc.pi_key_check[4 - (i % KEY_SIZE)];
+        p_buffer[ i ] ^= p_css->disc.pi_key_check[ 4 - (i % KEY_SIZE) ];
     }
-    memcpy( p_css->disc.pi_key_check, dvd.disckey.value, 2048 );
-#endif
+    memcpy( p_css->disc.pi_key_check, p_buffer, 2048 );
+
     /* Test authentication success */
-    switch( CSSGetASF( i_fd ) )
+    switch( CSSGetASF( p_css ) )
     {
-    case -1:
-    case 0:
-        free( p_css );
-        return NULL;
-    case 1:
-        return p_css;
+        case -1:
+        case 0:
+            return -1;
+
+        case 1:
+            return 0;
     }
 
-    return p_css;
+    return 0;
 
 #else /* HAVE_CSS */
     intf_ErrMsg( "css error: CSS decryption is disabled in this module" );
 
-    return NULL;
+    return -1;
+
 #endif /* HAVE_CSS */
 }
 
@@ -442,7 +389,7 @@ int CSSGetKey( css_t * p_css )
                     (dvd_key_t*)&pi_buf[0x54], &pi_key);
             }
 
-            /* Stop search if we find one occurance of the key 
+            /* Stop search if we find one occurence of the key 
              * I have never found a DVD for which it is not enough
              * but we should take care of that */
             if( i_registered_keys == 1 && p_title_key[0].i_occ >= 1 )
@@ -593,26 +540,25 @@ int CSSDescrambleSector( dvd_key_t pi_key, u8* pi_sec )
  *  0 if the device needs to be authenticated,
  *  1 either.
  *****************************************************************************/
-static int CSSGetASF( int i_fd )
+static int CSSGetASF( css_t *p_css )
 {
-    dvd_authinfo    auth_info;
-
-    auth_info.type = DVD_LU_SEND_ASF;
-    auth_info.lsasf.asf = 0;
+    int i_oldagid = p_css->i_agid, i_asf = 0;
 
-    for( auth_info.lsasf.agid = 0 ; auth_info.lsasf.agid < 4 ;
-                                                    auth_info.lsasf.agid++ )
+    for( p_css->i_agid = 0 ; p_css->i_agid < 4 ; p_css->i_agid++ )
     {
-        if( !( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) ) )
+        if( dvd_LUSendASF( p_css, &i_asf ) == 0 )
         {
-            intf_WarnMsg( 3, "css info: %sauthenticated",
-                          auth_info.lsasf.asf ? "" : "not " );
-            return auth_info.lsasf.asf;
+            intf_WarnMsg( 3, "css info: %sauthenticated", i_asf ? "":"not " );
+
+            p_css->i_agid = i_oldagid;
+            return i_asf;
         }
     }
 
     /* The ioctl process has failed */
     intf_ErrMsg( "css error: GetASF fatal error" );
+
+    p_css->i_agid = i_oldagid;
     return -1;
 }
 
index 41afb88dfd6cf78f414773064ffc42dd7fdb7d30..2f2e1901c88114d3778efc71e0c7415946b7930c 100644 (file)
@@ -2,7 +2,7 @@
  * dvd_css.h: Structures for DVD authentification and unscrambling
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_css.h,v 1.5 2001/03/03 07:07:01 stef Exp $
+ * $Id: dvd_css.h,v 1.6 2001/04/02 23:30:41 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -55,3 +55,4 @@ typedef struct css_s
     off_t           i_title_pos;
     dvd_key_t       pi_title_key;
 } css_t;
+
index bcf0d7a70461689f1f52499717d4c1d4f3d80a2f..b2b035529ef8f983239ee43951a76e72afc07bf9 100644 (file)
@@ -2,7 +2,7 @@
  * dvd_ioctl.c: DVD ioctl replacement function
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_ioctl.c,v 1.3 2001/03/05 11:53:44 sam Exp $
+ * $Id: dvd_ioctl.c,v 1.4 2001/04/02 23:30:41 sam Exp $
  *
  * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
  *          Samuel Hocevar <sam@zoy.org>
 
 #include <sys/types.h>
 #include <netinet/in.h>
-#ifdef HAVE_SYS_IOCTL_H
-#   include <sys/ioctl.h>
-#endif
 #ifdef HAVE_SYS_DVDIO_H
+#   include <sys/ioctl.h>
 #   include <sys/dvdio.h>
 #endif
 #ifdef LINUX_DVD
+#   include <sys/ioctl.h>
 #   include <linux/cdrom.h>
 #endif
 #ifdef SYS_BEOS
+#   include <sys/ioctl.h>
 #   include <malloc.h>
 #   include <scsi.h>
 #endif
+#ifdef SYS_DARWIN1_3
+#   include <sys/ioctl.h>
+#   include <DVDioctl/DVDioctl.h>
+#endif
 
 #include "common.h"
 #include "intf_msg.h"
 
+#include "dvd_css.h"
 #include "dvd_ioctl.h"
 
 /*****************************************************************************
  * Local prototypes - BeOS specific
  *****************************************************************************/
 #if defined( SYS_BEOS )
-static int  ReadData          ( int i_fd, dvd_struct *p_dvd );
-static int  ReadCopyright     ( int i_fd, dvd_struct *p_dvd );
-static int  ReadKey           ( int i_fd, dvd_struct *p_dvd );
-static int  ReadBCA           ( int i_fd, dvd_struct *p_dvd );
-static int  ReadManufacturer  ( int i_fd, dvd_struct *p_dvd );
-
-static void InitGenericCommand( struct cdrom_generic_command *p_cgc,
-                                void *buf, int i_len, int i_type );
-static void InitReadCommand   ( struct cdrom_generic_command *p_cgc,
-                                unsigned i_agid, unsigned i_type );
-static void InitWriteCommand  ( struct cdrom_generic_command *p_cgc,
-                                unsigned i_agid, unsigned i_type );
-
+static void InitCommand ( struct cdrom_generic_command *p_cgc,
+                          void *buf, int i_len, int i_type );
 static int  SendCommand ( int i_fd, struct cdrom_generic_command *p_cgc );
 #endif
 
 /*****************************************************************************
- * dvd_ioctl: DVD ioctl() wrapper
+ * dvd_ReadKey: 
  *****************************************************************************
- * Since the DVD ioctls do not exist on every machine, we provide this wrapper
- * so that it becomes easier to port them to any architecture.
+ * 
  *****************************************************************************/
-int dvd_ioctl( int i_fd, unsigned long i_op, void *p_arg )
+int dvd_ReadKey( css_t *p_css, u8 *p_key )
 {
 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
-    return( ioctl( i_fd, i_op, p_arg ) );
-
-#elif defined( SYS_BEOS )
+    int i_ret;
+    dvd_struct dvd;
 
-    int           i_ret;
-    unsigned char buf[20];
+    dvd.type = DVD_STRUCT_DISCKEY;
+    dvd.disckey.agid = p_css->i_agid;
 
-    struct cdrom_generic_command p_cgc;
+    memset( dvd.disckey.value, 0, 2048 );
 
-    dvd_struct *p_dvd = (dvd_struct *)p_arg;
-    dvd_authinfo *p_authinfo = (dvd_authinfo *)p_arg;
+    i_ret = ioctl( p_css->i_fd, DVD_READ_STRUCT, &dvd );
 
-    switch ( i_op )
+    if( i_ret < 0 )
     {
-        case DVD_AUTH: /* Request type is "authentication" */
-        {
-            memset( buf, 0, sizeof( buf ) );
-            InitGenericCommand( &p_cgc, buf, 0, CGC_DATA_READ );
-
-            switch( p_authinfo->type )
-            {
-                case DVD_LU_SEND_AGID: /* LU data send */
-
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_AGID" );
-
-                    InitReadCommand( &p_cgc, p_authinfo->lsa.agid, 0 );
-
-                    i_ret = SendCommand( i_fd, &p_cgc );
-
-                    p_authinfo->lsa.agid = buf[7] >> 6;
-
-                    return i_ret;
-
-                case DVD_LU_SEND_KEY1:
-
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_KEY1" );
-
-                    InitReadCommand( &p_cgc, p_authinfo->lsk.agid, 2 );
+        return i_ret;
+    }
 
-                    i_ret = SendCommand( i_fd, &p_cgc );
+    memcpy( p_key, dvd.disckey.value, 2048 );
+    return i_ret;
 
-                    /* Copy the key */
-                    memcpy( p_authinfo->lsk.key, &buf[4], sizeof(dvd_key) );
+#elif defined( SYS_BEOS )
+    int i_ret, size;
+    u8 p_buf[ 2048 + 4];
+    struct cdrom_generic_command cgc;
 
-                    return i_ret;
+    size = 2048 + 4;
 
-                case DVD_LU_SEND_CHALLENGE:
+    InitCommand( &cgc, p_buf, size, CGC_DATA_READ );
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_CHALLENGE" );
+    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
 
-                    InitReadCommand( &p_cgc, p_authinfo->lsc.agid, 1 );
+    cgc.cmd[7] = DVD_STRUCT_DISCKEY;
+    cgc.cmd[8] = size >> 8;
+    cgc.cmd[9] = size & 0xff;
+    cgc.cmd[10] = p_css->i_agid << 6;
 
-                    i_ret = SendCommand( i_fd, &p_cgc );
+    i_ret = SendCommand( p_css->i_fd, &cgc );
 
-                    /* Copy the challenge */
-                    memcpy( p_authinfo->lsc.chal, &buf[4],
-                            sizeof(dvd_challenge) );
+    if( i_ret < 0 )
+    {
+        return i_ret;
+    }
 
-                    return i_ret;
+    memcpy( p_key, p_buf + 4, 2048 );
+    return i_ret;
 
-                case DVD_LU_SEND_TITLE_KEY: /* Post-auth key */
+#else
+    return -1;
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_TITLE_KEY" );
+#endif
+}
 
-                    InitReadCommand( &p_cgc, p_authinfo->lstk.agid, 4 );
+/*****************************************************************************
+ * dvd_ReadCopyright: 
+ *****************************************************************************
+ * 
+ *****************************************************************************/
+int dvd_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
+{
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    int i_ret;
+    dvd_struct dvd;
 
-                    p_cgc.cmd[5] = p_authinfo->lstk.lba;
-                    p_cgc.cmd[4] = p_authinfo->lstk.lba >> 8;
-                    p_cgc.cmd[3] = p_authinfo->lstk.lba >> 16;
-                    p_cgc.cmd[2] = p_authinfo->lstk.lba >> 24;
+    dvd.type = DVD_STRUCT_COPYRIGHT;
+    dvd.copyright.layer_num = i_layer;
 
-                    i_ret = SendCommand( i_fd, &p_cgc );
+    i_ret = ioctl( i_fd, DVD_READ_STRUCT, &dvd );
 
-                    p_authinfo->lstk.cpm = (buf[4] >> 7) & 1;
-                    p_authinfo->lstk.cp_sec = (buf[4] >> 6) & 1;
-                    p_authinfo->lstk.cgms = (buf[4] >> 4) & 3;
+    *pi_copyright = dvd.copyright.cpst;
+    return i_ret;
 
-                    /* Copy the key */
-                    memcpy( p_authinfo->lstk.title_key, &buf[5],
-                            sizeof(dvd_key) );
+#elif defined( SYS_BEOS )
+    int i_ret;
+    u8 p_buf[8];
+    struct cdrom_generic_command cgc;
 
-                    return i_ret;
+    InitCommand( &cgc, p_buf, sizeof(p_buf), CGC_DATA_READ );
 
-                case DVD_LU_SEND_ASF:
+    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_ASF" );
+    cgc.cmd[6] = i_layer;
+    cgc.cmd[7] = DVD_STRUCT_COPYRIGHT;
+    cgc.cmd[8] = cgc.buflen >> 8;
+    cgc.cmd[9] = cgc.buflen & 0xff;
 
-                    InitReadCommand( &p_cgc, p_authinfo->lsasf.agid, 5 );
+    i_ret = SendCommand( i_fd, &cgc );
 
-                    i_ret = SendCommand( i_fd, &p_cgc );
+    *pi_copyright = p_buf[4];
+    return i_ret;
 
-                    p_authinfo->lsasf.asf = buf[7] & 1;
+#elif defined( SYS_DARWIN1_3 )
+    intf_ErrMsg( "css error: DVD ioctls not fully functional yet" );
+    intf_ErrMsg( "css error: assuming disc is unencrypted" );
 
-                    return i_ret;
+    *pi_copyright = 0;
+    return 0;
 
-                case DVD_HOST_SEND_CHALLENGE: /* LU data receive */
+#else
+    return -1;
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_CHALLENGE" );
+#endif
+}
 
-                    InitWriteCommand( &p_cgc, p_authinfo->hsc.agid, 1 );
-                    buf[1] = 0xe;
+/*****************************************************************************
+ * dvd_LUSendAgid: 
+ *****************************************************************************
+ * 
+ *****************************************************************************/
+int dvd_LUSendAgid( css_t *p_css )
+{
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    int i_ret;
+    dvd_authinfo auth_info;
 
-                    /* Copy the challenge */
-                    memcpy( &buf[4], p_authinfo->hsc.chal,
-                            sizeof(dvd_challenge) );
+    auth_info.type = DVD_LU_SEND_AGID;
+    auth_info.lsa.agid = p_css->i_agid;
 
-                    if( (i_ret = SendCommand(i_fd, &p_cgc)) )
-                    {
-                        return i_ret;
-                    }
+    i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
 
-                    p_authinfo->type = DVD_LU_SEND_KEY1;
+    p_css->i_agid = auth_info.lsa.agid;
+    return i_ret;
 
-                    return 0;
+#elif defined( SYS_BEOS )
+    u8 p_buf[8];
+    int i_ret;
+    struct cdrom_generic_command cgc;
 
-                case DVD_HOST_SEND_KEY2:
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_KEY2" );
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-                    InitWriteCommand( &p_cgc, p_authinfo->hsk.agid, 3 );
-                    buf[1] = 0xa;
+    cgc.cmd[0] = GPCMD_REPORT_KEY;
+    cgc.cmd[10] = 0x00 | (p_css->i_agid << 6);
+    cgc.buflen = 8;
+    cgc.cmd[9] = cgc.buflen;
+    cgc.data_direction = CGC_DATA_READ;
 
-                    /* Copy the key */
-                    memcpy( &buf[4], p_authinfo->hsk.key, sizeof(dvd_key) );
+    i_ret = SendCommand( p_css->i_fd, &cgc );
 
-                    if( (i_ret = SendCommand(i_fd, &p_cgc)) )
-                    {
-                        p_authinfo->type = DVD_AUTH_FAILURE;
-                        return i_ret;
-                    }
+    p_css->i_agid = p_buf[7] >> 6;
+    return i_ret;
 
-                    p_authinfo->type = DVD_AUTH_ESTABLISHED;
+#else
+    return -1;
 
-                    return 0;
+#endif
+}
 
-                case DVD_INVALIDATE_AGID: /* Misc */
+/*****************************************************************************
+ * dvd_InvalidateAgid: 
+ *****************************************************************************
+ * 
+ *****************************************************************************/
+int dvd_InvalidateAgid( css_t *p_css )
+{
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    int i_ret;
+    dvd_authinfo auth_info;
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_INVALIDATE_AGID" );
+    auth_info.type = DVD_INVALIDATE_AGID;
+    auth_info.lsa.agid = p_css->i_agid;
 
-                    InitReadCommand( &p_cgc, p_authinfo->lsa.agid, 0x3f );
+    i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
 
-                   return SendCommand( i_fd, &p_cgc );
+    p_css->i_agid = auth_info.lsa.agid;
+    return i_ret;
 
-                case DVD_LU_SEND_RPC_STATE: /* Get region settings */
+#elif defined( SYS_BEOS )
+    u8 p_buf[0];
+    struct cdrom_generic_command cgc;
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_LU_SEND_RPC_STATE "
-                                     "(unimplemented)" );
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-        #if 0
-                    p_dvdetup_report_key( &p_cgc, 0, 8 );
-                    memset( &rpc_state, 0, sizeof(rpc_state_t) );
-                    p_cgc.buffer = (char *) &rpc_state;
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-                    if( (i_ret = SendCommand(i_fd, &p_cgc)) )
-                    {
-                        return i_ret;
-                    }
+    cgc.cmd[0] = GPCMD_REPORT_KEY;
+    cgc.cmd[10] = 0x3f | (p_css->i_agid << 6);
+    cgc.cmd[9] = cgc.buflen = 0;
+    cgc.data_direction = CGC_DATA_READ;
 
-                    p_authinfo->lrpcs.type = rpc_state.type_code;
-                    p_authinfo->lrpcs.vra = rpc_state.vra;
-                    p_authinfo->lrpcs.ucca = rpc_state.ucca;
-                    p_authinfo->lrpcs.region_mask = rpc_state.region_mask;
-                    p_authinfo->lrpcs.rpc_scheme = rpc_state.rpc_scheme;
-        #endif
+    return SendCommand( p_css->i_fd, &cgc );
 
-                    return 0;
+#else
+    return -1;
 
-                case DVD_HOST_SEND_RPC_STATE: /* Set region settings */
+#endif
+}
 
-                    intf_WarnMsg( 2, "css DoAuth: DVD_HOST_SEND_RPC_STATE" );
+/*****************************************************************************
+ * dvd_HostSendChallenge: 
+ *****************************************************************************
+ * 
+ *****************************************************************************/
+int dvd_HostSendChallenge( css_t *p_css, u8 *p_challenge )
+{
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    dvd_authinfo auth_info;
 
-                    InitWriteCommand( &p_cgc, 0, 6 );
-                    buf[1] = 6;
-                    buf[4] = p_authinfo->hrpcs.pdrc;
+    auth_info.type = DVD_HOST_SEND_CHALLENGE;
 
-                    return SendCommand( i_fd, &p_cgc );
+    memcpy( auth_info.hsc.chal, p_challenge, sizeof(dvd_challenge) );
 
-                default:
-                    intf_ErrMsg( "css DoAuth: invalid DVD key ioctl" );
-                    return -1;
+    return ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
 
-            }
-        }
+#elif defined( SYS_BEOS )
+    u8 p_buf[16];
+    struct cdrom_generic_command cgc;
 
-        case DVD_READ_STRUCT: /* Request type is "read structure" */
-        {
-            switch( p_dvd->type )
-            {
-                case DVD_STRUCT_PHYSICAL:
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-                    intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_PHYSICAL" );
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-                    return ReadData( i_fd, p_dvd );
+    cgc.cmd[0] = GPCMD_SEND_KEY;
+    cgc.cmd[10] = 0x01 | (p_css->i_agid << 6);
+    cgc.buflen = 16;
+    cgc.cmd[9] = cgc.buflen;
+    cgc.data_direction = CGC_DATA_WRITE;
 
-                case DVD_STRUCT_COPYRIGHT:
+    p_buf[1] = 0xe;
+    memcpy( p_buf + 4, p_challenge, sizeof(dvd_challenge) );
 
-                    intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_COPYRIGHT" );
+    return SendCommand( p_css->i_fd, &cgc );
 
-                    return ReadCopyright( i_fd, p_dvd );
+#else
+    return -1;
 
-                case DVD_STRUCT_DISCKEY:
+#endif
+}
 
-                    intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_DISCKEY" );
+/*****************************************************************************
+ * dvd_LUSendASF: 
+ *****************************************************************************
+ * 
+ *****************************************************************************/
+int dvd_LUSendASF( css_t *p_css, int *pi_asf )
+{
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    int i_ret;
+    dvd_authinfo auth_info;
 
-                    return ReadKey( i_fd, p_dvd );
+    auth_info.type = DVD_LU_SEND_ASF;
+    auth_info.lsasf.agid = p_css->i_agid;
+    auth_info.lsasf.asf = *pi_asf;
 
-                case DVD_STRUCT_BCA:
+    i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
 
-                    intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_BCA" );
+    *pi_asf = auth_info.lsasf.asf;
+    return i_ret;
 
-                    return ReadBCA( i_fd, p_dvd );
+#elif defined( SYS_BEOS )
+    int i_ret;
+    u8 p_buf[8];
+    struct cdrom_generic_command cgc;
 
-                case DVD_STRUCT_MANUFACT:
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-                    intf_WarnMsg( 2, "css ReadStruct: DVD_STRUCT_MANUFACT" );
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-                    return ReadManufacturer( i_fd, p_dvd );
+    cgc.cmd[0] = GPCMD_REPORT_KEY;
+    cgc.cmd[10] = 0x05 | (p_css->i_agid << 6);
+    cgc.buflen = 8;
+    cgc.cmd[9] = cgc.buflen;
+    cgc.data_direction = CGC_DATA_READ;
 
-                default:
-                    intf_WarnMsg( 2, "css ReadStruct: invalid request (%d)",
-                                  p_dvd->type );
+    i_ret = SendCommand( p_css->i_fd, &cgc );
 
-                    return -1;
-            }
-        }
+    *pi_asf = p_buf[7] & 1;
+    return i_ret;
 
-        default: /* Unknown request type */
-        {
-            intf_ErrMsg( "css error: unknown command 0x%x", i_op );
-            return -1;
-        }
-    }
 #else
-
     return -1;
+
 #endif
 }
 
-/* Local prototypes */
-
-#if defined( SYS_BEOS )
 /*****************************************************************************
- * ReadData: Get data structure information from the DVD.
+ * dvd_LUSendChallenge: 
+ *****************************************************************************
+ * 
  *****************************************************************************/
-static int ReadData( int i_fd, dvd_struct *p_dvd )
+int dvd_LUSendChallenge( css_t *p_css, u8 *p_challenge )
 {
-    int i_ret, i;
-    u_char buf[4 + 4 * 20], *base;
-    struct dvd_layer *layer;
-    struct cdrom_generic_command cgc;
-
-    InitGenericCommand( &cgc, buf, sizeof(buf), CGC_DATA_READ );
-
-    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
-    cgc.cmd[6] = p_dvd->physical.layer_num;
-    cgc.cmd[7] = p_dvd->type;
-    cgc.cmd[9] = cgc.buflen & 0xff;
-
-    if( (i_ret = SendCommand(i_fd, &cgc)) )
-    {
-        return i_ret;
-    }
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    int i_ret;
+    dvd_authinfo auth_info;
 
-    base = &buf[4];
-    layer = &p_dvd->physical.layer[0];
+    auth_info.type = DVD_LU_SEND_CHALLENGE;
 
-    /* place the data... really ugly, but at least we won't have to
-     * worry about endianess in userspace or here. */
-    for( i = 0; i < 4; ++i, base += 20, ++layer )
-    {
-        memset( layer, 0, sizeof(*layer) );
-
-        layer->book_version = base[0] & 0xf;
-        layer->book_type = base[0] >> 4;
-        layer->min_rate = base[1] & 0xf;
-        layer->disc_size = base[1] >> 4;
-        layer->layer_type = base[2] & 0xf;
-        layer->track_path = (base[2] >> 4) & 1;
-        layer->nlayers = (base[2] >> 5) & 3;
-        layer->track_density = base[3] & 0xf;
-        layer->linear_density = base[3] >> 4;
-        layer->start_sector = base[5] << 16 | base[6] << 8 | base[7];
-        layer->end_sector = base[9] << 16 | base[10] << 8 | base[11];
-        layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
-        layer->bca = base[16] >> 7;
-    }
+    i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
 
-    return 0;
-}
+    memcpy( p_challenge, auth_info.lsc.chal, sizeof(dvd_challenge) );
+    return i_ret;
 
-/*****************************************************************************
- * ReadCopyright: get copyright information from the DVD.
- *****************************************************************************/
-static int ReadCopyright( int i_fd, dvd_struct *p_dvd )
-{
+#elif defined( SYS_BEOS )
     int i_ret;
-    u_char buf[8];
+    u8 p_buf[16];
     struct cdrom_generic_command cgc;
 
-    InitGenericCommand( &cgc, buf, sizeof(buf), CGC_DATA_READ );
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
-    cgc.cmd[6] = p_dvd->copyright.layer_num;
-    cgc.cmd[7] = p_dvd->type;
-    cgc.cmd[8] = cgc.buflen >> 8;
-    cgc.cmd[9] = cgc.buflen & 0xff;
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-    if( (i_ret = SendCommand(i_fd, &cgc)) )
-    {
-        return i_ret;
-    }
+    cgc.cmd[0] = GPCMD_REPORT_KEY;
+    cgc.cmd[10] = 0x01 | (p_css->i_agid << 6);
+    cgc.buflen = 16;
+    cgc.cmd[9] = cgc.buflen;
+    cgc.data_direction = CGC_DATA_READ;
 
-    p_dvd->copyright.cpst = buf[4];
-    p_dvd->copyright.rmi = buf[5];
+    i_ret = SendCommand( p_css->i_fd, &cgc );
 
-    return 0;
+    memcpy( p_challenge, p_buf + 4, sizeof(dvd_challenge) );
+    return i_ret;
+
+#else
+    return -1;
+
+#endif
 }
 
 /*****************************************************************************
- * ReadKey: get a key from the DVD.
+ * dvd_LUSendKey1: 
+ *****************************************************************************
+ * 
  *****************************************************************************/
-static int ReadKey( int i_fd, dvd_struct *p_dvd )
+int dvd_LUSendKey1( css_t *p_css, u8 *p_key )
 {
-    int i_ret, size;
-    u_char *buf;
-    struct cdrom_generic_command cgc;
-
-    size = sizeof( p_dvd->disckey.value ) + 4;
-
-#if 0
-    if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL)
-    {
-        return -ENOMEM;
-    }
-#endif
-    buf = (u_char *) malloc( size );
-
-    InitGenericCommand( &cgc, buf, size, CGC_DATA_READ );
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    int i_ret;
+    dvd_authinfo auth_info;
 
-    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
-    cgc.cmd[7] = p_dvd->type;
-    cgc.cmd[8] = size >> 8;
-    cgc.cmd[9] = size & 0xff;
-    cgc.cmd[10] = p_dvd->disckey.agid << 6;
+    auth_info.type = DVD_LU_SEND_KEY1;
+    auth_info.lsk.agid = p_css->i_agid;
 
-    if( !(i_ret = SendCommand(i_fd, &cgc)) )
-    {
-        memcpy( p_dvd->disckey.value, &buf[4], sizeof(p_dvd->disckey.value) );
-    }
+    i_ret = ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
 
-    free( buf );
+    memcpy( p_key, auth_info.lsk.key, sizeof(dvd_key) );
     return i_ret;
-}
 
-/*****************************************************************************
- * ReadBCA: read the Burst Cutting Area of a DVD.
- *****************************************************************************
- * The BCA is a special part of the DVD which is used to burn additional
- * data after it has been manufactured. DIVX is an exemple.
- *****************************************************************************/
-static int ReadBCA( int i_fd, dvd_struct *p_dvd )
-{
+#elif defined( SYS_BEOS )
     int i_ret;
-    u_char buf[4 + 188];
+    u8 p_buf[12];
     struct cdrom_generic_command cgc;
 
-    InitGenericCommand( &cgc, buf, sizeof(buf), CGC_DATA_READ );
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
-    cgc.cmd[7] = p_dvd->type;
-    cgc.cmd[9] = cgc.buflen = 0xff;
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-    if( (i_ret = SendCommand(i_fd, &cgc)) )
-    {
-        return i_ret;
-    }
+    cgc.cmd[0] = GPCMD_REPORT_KEY;
+    cgc.cmd[10] = 0x02 | (p_css->i_agid << 6);
+    cgc.buflen = 12;
+    cgc.cmd[9] = cgc.buflen;
+    cgc.data_direction = CGC_DATA_READ;
 
-    p_dvd->bca.len = buf[0] << 8 | buf[1];
-    if( p_dvd->bca.len < 12 || p_dvd->bca.len > 188 )
-    {
-        intf_ErrMsg( "css error: invalid BCA length (%d)", p_dvd->bca.len );
-        return -1;
-    }
+    i_ret = SendCommand( p_css->i_fd, &cgc );
 
-    memcpy( p_dvd->bca.value, &buf[4], p_dvd->bca.len );
+    memcpy( p_key, p_buf + 4, sizeof(dvd_key) );
+    return i_ret;
 
-    return 0;
+#else
+    return -1;
+
+#endif
 }
 
 /*****************************************************************************
- * ReadManufacturer: get manufacturer information from the DVD.
+ * dvd_HostSendKey2: 
+ *****************************************************************************
+ * 
  *****************************************************************************/
-static int ReadManufacturer( int i_fd, dvd_struct *p_dvd )
+int dvd_HostSendKey2( css_t *p_css, u8 *p_key )
 {
-    int i_ret = 0, size;
-    u_char *buf;
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+    dvd_authinfo auth_info;
+
+    auth_info.type = DVD_HOST_SEND_KEY2;
+    auth_info.hsk.agid = p_css->i_agid;
+
+    memcpy( auth_info.hsk.key, p_key, sizeof(dvd_key) );
+
+    return ioctl( p_css->i_fd, DVD_AUTH, &auth_info );
+
+#elif defined( SYS_BEOS )
+    u8 p_buf[12];
     struct cdrom_generic_command cgc;
 
-    size = sizeof( p_dvd->manufact.value ) + 4;
+    //memset( p_buf, 0, sizeof( p_buf ) );
 
-#if 0
-    if( (buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL )
-    {
-        return -ENOMEM;
-    }
-#endif
-    buf = (u_char *) malloc(size);
+    InitCommand( &cgc, p_buf, 0, CGC_DATA_READ );
 
-    InitGenericCommand( &cgc, buf, size, CGC_DATA_READ );
+    cgc.cmd[0] = GPCMD_SEND_KEY;
+    cgc.cmd[10] = 0x3 | (p_css->i_agid << 6);
+    cgc.buflen = 12;
+    cgc.cmd[9] = cgc.buflen;
+    cgc.data_direction = CGC_DATA_WRITE;
 
-    cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
-    cgc.cmd[7] = p_dvd->type;
-    cgc.cmd[8] = size >> 8;
-    cgc.cmd[9] = size & 0xff;
+    p_buf[1] = 0xa;
+    memcpy( p_buf + 4, p_key, sizeof(dvd_key) );
 
-    if( (i_ret = SendCommand(i_fd, &cgc)) )
-    {
-        return i_ret;
-    }
+    return SendCommand( p_css->i_fd, &cgc );
 
-    p_dvd->manufact.len = buf[0] << 8 | buf[1];
-    if( p_dvd->manufact.len < 0 || p_dvd->manufact.len > 2048 )
-    {
-        intf_ErrMsg( "css error: invalid manufacturer info length (%d)",
-                     p_dvd->bca.len );
-        i_ret = -1;
-    }
-    else
-    {
-        memcpy( p_dvd->manufact.value, &buf[4], p_dvd->manufact.len );
-    }
+#else
+    return -1;
 
-    free( buf );
-    return i_ret;
+#endif
 }
 
+/* Local prototypes */
+
+#if defined( SYS_BEOS )
 /*****************************************************************************
- * InitGenericCommand: initialize a CGC structure
+ * InitCommand: initialize a CGC structure
  *****************************************************************************
  * This function initializes a CDRom Generic Command structure for
  * future use, either a read command or a write command.
  *****************************************************************************/
-static void InitGenericCommand( struct cdrom_generic_command *p_cgc,
-                                void *buf, int i_len, int i_type )
+static void InitCommand( struct cdrom_generic_command *p_cgc,
+                         void *p_buf, int i_len, int i_type )
 {
     memset( p_cgc, 0, sizeof( struct cdrom_generic_command ) );
 
-    if( buf != NULL )
+    if( p_buf != NULL )
     {
-        memset( buf, 0, i_len );
+        memset( p_buf, 0, i_len );
     }
 
-    p_cgc->buffer = ( char * )buf;
+    p_cgc->buffer = ( char * )p_buf;
     p_cgc->buflen = i_len;
     p_cgc->data_direction = i_type;
     p_cgc->timeout = 255;
 }
 
-/*****************************************************************************
- * InitReadCommand: fill a CGC structure for reading purposes.
- *****************************************************************************
- * This function fills a CDRom Generic Command for a command which will
- * read data from the DVD.
- *****************************************************************************/
-static void InitReadCommand( struct cdrom_generic_command *p_cgc,
-                             unsigned i_agid, unsigned i_type )
-{
-    p_cgc->cmd[0] = GPCMD_REPORT_KEY;
-    p_cgc->cmd[10] = i_type | (i_agid << 6);
-
-    /* FIXME: check what i_type means */
-    switch( i_type )
-    {
-        case 0:
-        case 8:
-        case 5:
-            p_cgc->buflen = 8;
-            break;
-
-        case 1:
-            p_cgc->buflen = 16;
-            break;
-
-        case 2:
-        case 4:
-            p_cgc->buflen = 12;
-            break;
-    }
-
-    p_cgc->cmd[9] = p_cgc->buflen;
-    p_cgc->data_direction = CGC_DATA_READ;
-}
-
-/*****************************************************************************
- * InitWriteCommand: fill a CGC structure for writing purposes.
- *****************************************************************************
- * This function fills a CDRom Generic Command for a command which will
- * send data to the DVD.
- *****************************************************************************/
-static void InitWriteCommand( struct cdrom_generic_command *p_cgc,
-                              unsigned i_agid, unsigned i_type )
-{
-    p_cgc->cmd[0] = GPCMD_SEND_KEY;
-    p_cgc->cmd[10] = i_type | (i_agid << 6);
-
-    /* FIXME: check what i_type means */
-    switch( i_type )
-    {
-        case 1:
-            p_cgc->buflen = 16;
-            break;
-
-        case 3:
-            p_cgc->buflen = 12;
-            break;
-
-        case 6:
-            p_cgc->buflen = 8;
-            break;
-    }
-
-    p_cgc->cmd[9] = p_cgc->buflen;
-    p_cgc->data_direction = CGC_DATA_WRITE;
-}
-
 /*****************************************************************************
  * SendCommand: send a raw device command to the DVD drive.
  *****************************************************************************
index a7096661ea1ca5f18d2961713cc0cde59f7187b4..a6263f3d2db9d3f597814af833716e19683bedf1 100644 (file)
@@ -2,7 +2,7 @@
  * dvd_ioctl.h: DVD ioctl replacement function
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_ioctl.h,v 1.3 2001/03/06 10:21:59 massiot Exp $
+ * $Id: dvd_ioctl.h,v 1.4 2001/04/02 23:30:41 sam Exp $
  *
  * Authors: David Giller <rafetmad@oxy.edu>
  *          Eberhard Moenkeberg <emoenke@gwdg.de>
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
+int dvd_ReadCopyright     ( int i_fd, int i_layer, int *pi_copyright );
+
+int dvd_ReadKey           ( css_t *p_css, u8 *p_key );
+int dvd_LUSendAgid        ( css_t *p_css );
+int dvd_LUSendChallenge   ( css_t *p_css, u8 *p_challenge );
+int dvd_LUSendKey1        ( css_t *p_css, u8 *p_key );
+int dvd_LUSendASF         ( css_t *p_css, int *pi_asf );
+int dvd_InvalidateAgid    ( css_t *p_css );
+int dvd_HostSendChallenge ( css_t *p_css, u8 *p_challenge );
+int dvd_HostSendKey2      ( css_t *p_css, u8 *p_key );
+
 int dvd_ioctl( int i_fd, unsigned long i_op, void *p_arg );
 
 /*****************************************************************************
index 43c8609c3c59f88c5227c26838665616baec1621..8e13a243023dcde9e9734c3ab66a70aa433d4648 100644 (file)
@@ -10,7 +10,7 @@
  *  -dvd_udf to find files
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: input_dvd.c,v 1.35 2001/04/01 07:31:38 stef Exp $
+ * $Id: input_dvd.c,v 1.36 2001/04/02 23:30:41 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -243,7 +243,6 @@ lang_tbl[] =
  * Local prototypes
  *****************************************************************************/
 static int  DVDProbe    ( probedata_t *p_data );
-static int  DVDCheckCSS ( struct input_thread_s * );
 static int  DVDRead     ( struct input_thread_s *, data_packet_t ** );
 static void DVDInit     ( struct input_thread_s * );
 static void DVDEnd      ( struct input_thread_s * );
@@ -340,15 +339,6 @@ static int DVDProbe( probedata_t *p_data )
     return( i_score );
 }
 
-/*****************************************************************************
- * DVDCheckCSS: check the stream
- *****************************************************************************/
-static int DVDCheckCSS( input_thread_t * p_input )
-{
-    return CSSTest( p_input->i_handle );
-}
-
-
 /*****************************************************************************
  * DVDFindCell: adjust the title cell index with the program cell
  *****************************************************************************/
@@ -744,7 +734,8 @@ static void DVDInit( input_thread_t * p_input )
     int                  i_chapter;
     int                  i;
 
-    if( (p_dvd = malloc( sizeof(thread_dvd_data_t) )) == NULL )
+    p_dvd = malloc( sizeof(thread_dvd_data_t) );
+    if( p_dvd == NULL )
     {
         intf_ErrMsg( "Out of memory" );
         p_input->b_error = 1;
@@ -759,7 +750,17 @@ static void DVDInit( input_thread_t * p_input )
     p_dvd->i_block_once = 32;
     p_input->i_read_once = 128;
 
-    p_dvd->b_encrypted = DVDCheckCSS( p_input );
+    i = CSSTest( p_input->i_handle );
+
+    if( i < 0 )
+    {
+        intf_ErrMsg( "css error: could not get copyright bit" );
+        free( p_dvd );
+        p_input->b_error = 1;
+        return;
+    }
+
+    p_dvd->b_encrypted = i;
 
     lseek( p_input->i_handle, 0, SEEK_SET );
 
@@ -771,20 +772,31 @@ static void DVDInit( input_thread_t * p_input )
     /* Ifo initialisation */
     if( IfoInit( &p_dvd->p_ifo, p_input->i_handle ) < 0 )
     {
-            intf_ErrMsg( "ifo error: fatal failure" );
-            free( p_dvd );
-            p_input->b_error = 1;
-            return;
+        intf_ErrMsg( "ifo error: fatal failure" );
+        free( p_dvd );
+        p_input->b_error = 1;
+        return;
     }
 
     /* CSS initialisation */
     if( p_dvd->b_encrypted )
     {
-        p_dvd->p_css = CSSInit( p_input->i_handle );
-
+        p_dvd->p_css = malloc( sizeof(css_t) );
         if( p_dvd->p_css == NULL )
+        {
+            intf_ErrMsg( "css error: couldn't create CSS structure" );
+            free( p_dvd );
+            p_input->b_error = 1;
+            return;
+        }
+
+        p_dvd->p_css->i_fd = p_input->i_handle;
+        p_dvd->p_css->i_agid = 0;
+
+        if( CSSInit( p_dvd->p_css ) )
         {
             intf_ErrMsg( "css error: fatal failure" );
+            free( p_dvd->p_css );
             free( p_dvd );
             p_input->b_error = 1;
             return;
@@ -865,6 +877,7 @@ static void DVDEnd( input_thread_t * p_input )
     if( p_dvd->b_encrypted )
     {
         CSSEnd( p_dvd->p_css );
+        free( p_dvd->p_css );
     }
 
     IfoEnd( p_dvd->p_ifo );
index aef55375adddefe2a477ef9d0c27104ed79d9b65..92d2c3df5bedc14ca63da43770c7b8b47bb074c1 100644 (file)
@@ -2,7 +2,7 @@
  * input_dvd.h: thread structure of the DVD plugin
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: input_dvd.h,v 1.14 2001/04/01 07:31:38 stef Exp $
+ * $Id: input_dvd.h,v 1.15 2001/04/02 23:30:41 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -74,9 +74,9 @@ void  IfoEnd      ( struct ifo_s * );
 /*****************************************************************************
  * Prototypes in dvd_css.c
  *****************************************************************************/
-int             CSSTest             ( int );
-struct css_s *  CSSInit             ( int );
-void            CSSEnd              ( struct css_s * );
-int             CSSGetKey           ( struct css_s * );
-int             CSSDescrambleSector ( u8 * , u8 * );
+int   CSSTest             ( int );
+int   CSSInit             ( struct css_s * );
+void  CSSEnd              ( struct css_s * );
+int   CSSGetKey           ( struct css_s * );
+int   CSSDescrambleSector ( u8 * , u8 * );
 
index f3643e37fcf84f469d9ad4b0fdbb0772b0aa5f8e..21bc9a127dfc0d3180d1f3ea76630aea52959af1 100644 (file)
@@ -2,7 +2,7 @@
  * lpcm_decoder_thread.c: lpcm decoder thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: lpcm_decoder_thread.c,v 1.11 2001/03/21 13:42:34 sam Exp $
+ * $Id: lpcm_decoder_thread.c,v 1.12 2001/04/02 23:30:41 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -46,7 +46,7 @@
 #include "lpcm_decoder.h"
 #include "lpcm_decoder_thread.h"
 
-#define LPCMDEC_FRAME_SIZE (2*1536)                    /* May not be usefull */
+#define LPCMDEC_FRAME_SIZE (2*1536)                        /* May be useless */
 
 /*****************************************************************************
  * Local prototypes