shithub: libdvdcss

Download patch

ref: 7325feef5443a3897085c7e1b2ffae8e3506e8ca
parent: 3d52f9e245f7f3307686743533d28d412cafd500
author: Diego Biurrun <diego@biurrun.de>
date: Fri Oct 24 06:32:47 EDT 2014

Drop support for ASPI disc access (and thus Windows 9x).

The ASPI access method is only relevant on Windows 9x versions where no
alternative exists. However, These Windows versions are obsolete since a
long time and have no more real world usage. Also, the ASPI code is ugly
and a maintenance burden.

--- a/NEWS
+++ b/NEWS
@@ -5,10 +5,9 @@
     - the function dvdcss_title()
     - the type dvdcss_handle
     - the variable dvdcss_interface_2
-  * Drop support for Windows 98 and Windows NT 4.0.
-    Windows 98 SE with IE 5.0 and Windows NT 4.0 SP4 with IE 5.0 are required.
   * Support for Android
-  * Drop support for HP-UX.
+  * Drop support for HP-UX, Windows 9x, and Windows NT 4.0.
+    Windows NT 4.0 SP4 with IE 5.0 is now required.
 
 
 Changes between 1.2.12 and 1.2.13:
--- a/libdvdcss.spec.in
+++ b/libdvdcss.spec.in
@@ -32,8 +32,8 @@
 libdvdcss is a simple library designed for accessing DVDs like a block device
 without having to bother about the decryption. The important features are:
  * Portability: Currently supported platforms are GNU/Linux, FreeBSD, NetBSD,
-   OpenBSD, BeOS, Mac OS X, Solaris, OS/2, Windows 98 SE (with IE 5.0) or
-   later, and Windows NT 4.0 (with IE 5.0) or later.
+   OpenBSD, BeOS, Mac OS X, Solaris, OS/2, and Windows NT 4.0 SP4 (with IE 5.0)
+   or later.
  * Adaptability: Unlike most similar projects, libdvdcss does not require the
    region of your drive to be set and will try its best to read from the disc
    even in the case of a region mismatch.
@@ -49,8 +49,8 @@
 libdvdcss is a simple library designed for accessing DVDs like a block device
 without having to bother about the decryption. The important features are:
  * Portability: Currently supported platforms are GNU/Linux, FreeBSD, NetBSD,
-   OpenBSD, BeOS, Mac OS X, Solaris, OS/2, Windows 98 SE (with IE 5.0) or
-   later, and Windows NT 4.0 (with IE 5.0) or later.
+   OpenBSD, BeOS, Mac OS X, Solaris, OS/2, and Windows NT 4.0 SP4 (with IE 5.0)
+   or later.
  * Adaptability: Unlike most similar projects, libdvdcss does not require the
    region of your drive to be set and will try its best to read from the disc
    even in the case of a region mismatch.
--- a/src/device.c
+++ b/src/device.c
@@ -84,14 +84,10 @@
 
 #ifdef WIN32
 static int win2k_open ( dvdcss_t, const char * );
-static int aspi_open  ( dvdcss_t, const char * );
 static int win2k_seek ( dvdcss_t, int );
-static int aspi_seek  ( dvdcss_t, int );
 static int win2k_read ( dvdcss_t, void *, int );
-static int aspi_read  ( dvdcss_t, void *, int );
 static int win_readv  ( dvdcss_t, struct iovec *, int );
 
-static int aspi_read_internal  ( int, void *, int );
 #elif defined( __OS2__ )
 static int os2_open ( dvdcss_t, const char * );
 /* just use macros for libc */
@@ -362,7 +358,7 @@
     dvdcss->p_readv_buffer   = NULL;
     dvdcss->i_readv_buf_size = 0;
 
-    if( !dvdcss->b_file && WIN2K )
+    if( !dvdcss->b_file )
     {
         print_debug( dvdcss, "using Win2K API for access" );
         dvdcss->pf_seek  = win2k_seek;
@@ -370,14 +366,6 @@
         dvdcss->pf_readv = win_readv;
         return win2k_open( dvdcss, psz_device );
     }
-    else if( !dvdcss->b_file )
-    {
-        print_debug( dvdcss, "using ASPI for access" );
-        dvdcss->pf_seek  = aspi_seek;
-        dvdcss->pf_read  = aspi_read;
-        dvdcss->pf_readv = win_readv;
-        return aspi_open( dvdcss, psz_device );
-    }
     else
 #elif defined( __OS2__ )
     /* If device is "X:" or "X:\", we are not actually opening a file. */
@@ -429,19 +417,11 @@
     {
         close( dvdcss->i_fd );
     }
-    else if( WIN2K )
+    else
     {
         CloseHandle( (HANDLE) dvdcss->i_fd );
     }
-    else /* ASPI */
-    {
-        struct w32_aspidev *fd = (struct w32_aspidev *) dvdcss->i_fd;
 
-        /* Unload ASPI and free w32_aspidev structure */
-        FreeLibrary( (HMODULE) fd->hASPI );
-        free( (void*) dvdcss->i_fd );
-    }
-
     /* Free readv temporary buffer */
     free( dvdcss->p_readv_buffer );
     dvdcss->p_readv_buffer   = NULL;
@@ -527,124 +507,6 @@
     print_error( dvdcss, "failed opening device" );
     return -1;
 }
-
-static int aspi_open( dvdcss_t dvdcss, const char *psz_device )
-{
-    HMODULE hASPI;
-    DWORD dwSupportInfo;
-    struct w32_aspidev *fd;
-    int i, j, i_hostadapters;
-    GETASPI32SUPPORTINFO lpGetSupport;
-    SENDASPI32COMMAND lpSendCommand;
-    char c_drive = psz_device[0];
-
-    /* load ASPI and init w32_aspidev structure */
-    hASPI = LoadLibrary( "wnaspi32.dll" );
-    if( hASPI == NULL )
-    {
-        print_error( dvdcss, "unable to load wnaspi32.dll" );
-        return -1;
-    }
-
-    lpGetSupport = (GETASPI32SUPPORTINFO) GetProcAddress( hASPI, "GetASPI32SupportInfo" );
-    lpSendCommand = (SENDASPI32COMMAND) GetProcAddress( hASPI, "SendASPI32Command" );
-
-    if(lpGetSupport == NULL || lpSendCommand == NULL )
-    {
-        print_error( dvdcss, "unable to get ASPI function pointers" );
-        FreeLibrary( hASPI );
-        return -1;
-    }
-
-    dwSupportInfo = lpGetSupport();
-
-    if( HIBYTE( LOWORD ( dwSupportInfo ) ) == SS_NO_ADAPTERS )
-    {
-        print_error( dvdcss, "no ASPI adapters found" );
-        FreeLibrary( hASPI );
-        return -1;
-    }
-
-    if( HIBYTE( LOWORD ( dwSupportInfo ) ) != SS_COMP )
-    {
-        print_error( dvdcss, "unable to initialize ASPI layer" );
-        FreeLibrary( hASPI );
-        return -1;
-    }
-
-    i_hostadapters = LOBYTE( LOWORD( dwSupportInfo ) );
-    if( i_hostadapters == 0 )
-    {
-        print_error( dvdcss, "no ASPI adapters ready" );
-        FreeLibrary( hASPI );
-        return -1;
-    }
-
-    fd = malloc( sizeof( struct w32_aspidev ) );
-    if( fd == NULL )
-    {
-        print_error( dvdcss, "not enough memory" );
-        FreeLibrary( hASPI );
-        return -1;
-    }
-
-    fd->i_blocks = 0;
-    fd->hASPI = (long) hASPI;
-    fd->lpSendCommand = lpSendCommand;
-
-    c_drive = c_drive > 'Z' ? c_drive - 'a' : c_drive - 'A';
-
-    for( i = 0; i < i_hostadapters; i++ )
-    {
-        for( j = 0; j < 15; j++ )
-        {
-            struct SRB_GetDiskInfo srbDiskInfo;
-
-            srbDiskInfo.SRB_Cmd         = SC_GET_DISK_INFO;
-            srbDiskInfo.SRB_HaId        = i;
-            srbDiskInfo.SRB_Flags       = 0;
-            srbDiskInfo.SRB_Hdr_Rsvd    = 0;
-            srbDiskInfo.SRB_Target      = j;
-            srbDiskInfo.SRB_Lun         = 0;
-
-            lpSendCommand( (void*) &srbDiskInfo );
-
-            if( (srbDiskInfo.SRB_Status == SS_COMP) &&
-                (srbDiskInfo.SRB_Int13HDriveInfo == c_drive) )
-            {
-                /* Make sure this is a CD-ROM device */
-                struct SRB_GDEVBlock srbGDEVBlock = { 0 };
-
-                srbGDEVBlock.SRB_Cmd    = SC_GET_DEV_TYPE;
-                srbGDEVBlock.SRB_HaId   = i;
-                srbGDEVBlock.SRB_Target = j;
-
-                lpSendCommand( (void*) &srbGDEVBlock );
-
-                if( ( srbGDEVBlock.SRB_Status == SS_COMP ) &&
-                    ( srbGDEVBlock.SRB_DeviceType == DTYPE_CDROM ) )
-                {
-                    fd->i_sid = MAKEWORD( i, j );
-                    dvdcss->i_fd = (int) fd;
-                    dvdcss->i_pos = 0;
-                    return 0;
-                }
-                else
-                {
-                    free( fd );
-                    FreeLibrary( hASPI );
-                    print_error( dvdcss,"this is not a CD-ROM drive" );
-                    return -1;
-                }
-            }
-        }
-    }
-
-    free( (void*) fd );
-    FreeLibrary( hASPI );
-    print_error( dvdcss, "unable to get haid and target (ASPI)" );
-    return -1;
-}
 #endif
 
 #ifdef __OS2__
@@ -733,35 +595,6 @@
 
     return dvdcss->i_pos;
 }
-
-static int aspi_seek( dvdcss_t dvdcss, int i_blocks )
-{
-    int i_old_blocks;
-    char sz_buf[ DVDCSS_BLOCK_SIZE ];
-    struct w32_aspidev *fd = (struct w32_aspidev *) dvdcss->i_fd;
-
-    if( dvdcss->i_pos == i_blocks )
-    {
-        /* We are already in position */
-        return i_blocks;
-    }
-
-    i_old_blocks = fd->i_blocks;
-    fd->i_blocks = i_blocks;
-
-    if( aspi_read_internal( dvdcss->i_fd, sz_buf, 1 ) == -1 )
-    {
-        fd->i_blocks = i_old_blocks;
-        dvdcss->i_pos = -1;
-        return -1;
-    }
-
-    (fd->i_blocks)--;
-
-    dvdcss->i_pos = fd->i_blocks;
-
-    return dvdcss->i_pos;
-}
 #endif
 
 /*****************************************************************************
@@ -817,20 +650,6 @@
     dvdcss->i_pos += i_bytes / DVDCSS_BLOCK_SIZE;
     return i_bytes / DVDCSS_BLOCK_SIZE;
 }
-
-static int aspi_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks )
-{
-    int i_read = aspi_read_internal( dvdcss->i_fd, p_buffer, i_blocks );
-
-    if( i_read < 0 )
-    {
-        dvdcss->i_pos = -1;
-        return i_read;
-    }
-
-    dvdcss->i_pos += i_read;
-    return i_read;
-}
 #endif
 
 /*****************************************************************************
@@ -905,7 +724,7 @@
 
 #if defined( WIN32 )
 /*****************************************************************************
- * win_readv: vectored read using ReadFile for Win2K and ASPI for win9x
+ * win_readv: vectored read using ReadFile for Win2K
  *****************************************************************************/
 static int win_readv ( dvdcss_t dvdcss, struct iovec *p_iovec, int i_blocks )
 {
@@ -941,31 +760,16 @@
 
     i_blocks_total /= DVDCSS_BLOCK_SIZE;
 
-    if( WIN2K )
+    if( !ReadFile( (HANDLE)dvdcss->i_fd, dvdcss->p_readv_buffer,
+                   i_blocks_total * DVDCSS_BLOCK_SIZE, &i_bytes, NULL ) )
     {
-        if( !ReadFile( (HANDLE)dvdcss->i_fd, dvdcss->p_readv_buffer,
-                       i_blocks_total * DVDCSS_BLOCK_SIZE, &i_bytes, NULL ) )
-        {
-            /* The read failed... too bad.
-             * As in the POSIX spec the file position is left
-             * unspecified after a failure */
-            dvdcss->i_pos = -1;
-            return -1;
-        }
-        i_blocks_read = i_bytes / DVDCSS_BLOCK_SIZE;
+        /* The read failed... too bad.
+         * As in the POSIX spec the file position is left
+         * unspecified after a failure */
+        dvdcss->i_pos = -1;
+        return -1;
     }
-    else /* Win9x */
-    {
-        i_blocks_read = aspi_read_internal( dvdcss->i_fd,
-                                            dvdcss->p_readv_buffer,
-                                            i_blocks_total );
-        if( i_blocks_read < 0 )
-        {
-            /* See above */
-            dvdcss->i_pos = -1;
-            return -1;
-        }
-    }
+    i_blocks_read = i_bytes / DVDCSS_BLOCK_SIZE;
 
     /* We just have to copy the content of the temp buffer into the iovecs */
     for( i_index = 0, i_blocks_total = i_blocks_read;
@@ -984,83 +788,5 @@
 
     dvdcss->i_pos += i_blocks_read;
     return i_blocks_read;
-}
-
-static int aspi_read_internal( int i_fd, void *p_data, int i_blocks )
-{
-    HANDLE hEvent;
-    struct SRB_ExecSCSICmd ssc = { 0 };
-    struct w32_aspidev *fd = (struct w32_aspidev *) i_fd;
-
-    /* Create the transfer completion event */
-    hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
-    if( hEvent == NULL )
-    {
-        return -1;
-    }
-
-    ssc.SRB_Cmd         = SC_EXEC_SCSI_CMD;
-    ssc.SRB_Flags       = SRB_DIR_IN | SRB_EVENT_NOTIFY;
-    ssc.SRB_HaId        = LOBYTE( fd->i_sid );
-    ssc.SRB_Target      = HIBYTE( fd->i_sid );
-    ssc.SRB_SenseLen    = SENSE_LEN;
-
-    ssc.SRB_PostProc = (LPVOID) hEvent;
-    ssc.SRB_BufPointer  = p_data;
-    ssc.SRB_CDBLen      = 12;
-
-    ssc.CDBByte[0]      = 0xA8; /* RAW */
-    ssc.CDBByte[2]      = (UCHAR) (fd->i_blocks >> 24);
-    ssc.CDBByte[3]      = (UCHAR) (fd->i_blocks >> 16) & 0xff;
-    ssc.CDBByte[4]      = (UCHAR) (fd->i_blocks >> 8) & 0xff;
-    ssc.CDBByte[5]      = (UCHAR) (fd->i_blocks) & 0xff;
-
-    /* We have to break down the reads into 64KB pieces (ASPI restriction) */
-    if( i_blocks > 32 )
-    {
-        ssc.SRB_BufLen = 32 * DVDCSS_BLOCK_SIZE;
-        ssc.CDBByte[9] = 32;
-        fd->i_blocks  += 32;
-
-        /* Initiate transfer */
-        ResetEvent( hEvent );
-        fd->lpSendCommand( (void*) &ssc );
-
-        /* transfer the next 64KB (aspi_read_internal is called recursively)
-         * We need to check the status of the read on return */
-        if( aspi_read_internal( i_fd,
-                                (uint8_t*) p_data + 32 * DVDCSS_BLOCK_SIZE,
-                                i_blocks - 32) < 0 )
-        {
-            return -1;
-        }
-    }
-    else
-    {
-        /* This is the last transfer */
-        ssc.SRB_BufLen   = i_blocks * DVDCSS_BLOCK_SIZE;
-        ssc.CDBByte[9]   = (UCHAR) i_blocks;
-        fd->i_blocks += i_blocks;
-
-        /* Initiate transfer */
-        ResetEvent( hEvent );
-        fd->lpSendCommand( (void*) &ssc );
-
-    }
-
-    /* If the command has still not been processed, wait until it's finished */
-    if( ssc.SRB_Status == SS_PENDING )
-    {
-        WaitForSingleObject( hEvent, INFINITE );
-    }
-    CloseHandle( hEvent );
-
-    /* check that the transfer went as planned */
-    if( ssc.SRB_Status != SS_COMP )
-    {
-      return -1;
-    }
-
-    return i_blocks;
 }
 #endif
--- a/src/ioctl.c
+++ b/src/ioctl.c
@@ -103,12 +103,10 @@
 #endif
 
 /*****************************************************************************
- * Local prototypes, win32 (aspi) specific
+ * Local prototypes, Win32 specific
  *****************************************************************************/
 #if defined( WIN32 )
 static void WinInitSPTD ( SCSI_PASS_THROUGH_DIRECT *, int );
-static void WinInitSSC  ( struct SRB_ExecSCSICmd *, int );
-static int  WinSendSSC  ( int, struct SRB_ExecSCSICmd * );
 #endif
 
 /*****************************************************************************
@@ -188,35 +186,21 @@
     *pi_copyright = dvdbs.copyrightProtectionSystemType;
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/2k/XP */
-    {
-        INIT_SPTD( GPCMD_READ_DVD_STRUCTURE, 8 );
+    INIT_SPTD( GPCMD_READ_DVD_STRUCTURE, 8 );
 
-        /*  When using IOCTL_DVD_READ_STRUCTURE and
-            DVD_COPYRIGHT_DESCRIPTOR, CopyrightProtectionType
-            seems to be always 6 ???
-            To work around this MS bug we try to send a raw SCSI command
-            instead (if we've got enough privileges to do so). */
+    /*  When using IOCTL_DVD_READ_STRUCTURE and
+        DVD_COPYRIGHT_DESCRIPTOR, CopyrightProtectionType
+        seems to be always 6 ???
+        To work around this MS bug we try to send a raw SCSI command
+        instead (if we've got enough privileges to do so). */
 
-        sptd.Cdb[ 6 ] = i_layer;
-        sptd.Cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;
+    sptd.Cdb[ 6 ] = i_layer;
+    sptd.Cdb[ 7 ] = DVD_STRUCT_COPYRIGHT;
 
-        i_ret = SEND_SPTD( i_fd, &sptd, &tmp );
+    i_ret = SEND_SPTD( i_fd, &sptd, &tmp );
 
-        if( i_ret == 0 )
-        {
-            *pi_copyright = p_buffer[ 4 ];
-        }
-    }
-    else
+    if( i_ret == 0 )
     {
-        INIT_SSC( GPCMD_READ_DVD_STRUCTURE, 8 );
-
-        ssc.CDBByte[ 6 ] = i_layer;
-        ssc.CDBByte[ 7 ] = DVD_STRUCT_COPYRIGHT;
-
-        i_ret = WinSendSSC( i_fd, &ssc );
-
         *pi_copyright = p_buffer[ 4 ];
     }
 
@@ -329,44 +313,25 @@
     memcpy( p_key, dvdbs.discKeyStructures, DVD_DISCKEY_SIZE );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/2k/XP */
-    {
-        DWORD tmp;
-        uint8_t buffer[DVD_DISK_KEY_LENGTH] = { 0 };
-        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
+    DWORD tmp;
+    uint8_t buffer[DVD_DISK_KEY_LENGTH] = { 0 };
+    PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
 
-        key->KeyLength  = DVD_DISK_KEY_LENGTH;
-        key->SessionId  = *pi_agid;
-        key->KeyType    = DvdDiskKey;
-        key->KeyFlags   = 0;
+    key->KeyLength  = DVD_DISK_KEY_LENGTH;
+    key->SessionId  = *pi_agid;
+    key->KeyType    = DvdDiskKey;
+    key->KeyFlags   = 0;
 
-        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
-                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
+    i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
+            key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
 
-        if( i_ret < 0 )
-        {
-            return i_ret;
-        }
-
-        memcpy( p_key, key->KeyData, DVD_DISCKEY_SIZE );
-    }
-    else
+    if( i_ret < 0 )
     {
-        INIT_SSC( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
-
-        ssc.CDBByte[ 7 ]  = DVD_STRUCT_DISCKEY;
-        ssc.CDBByte[ 10 ] = *pi_agid << 6;
-
-        i_ret = WinSendSSC( i_fd, &ssc );
-
-        if( i_ret < 0 )
-        {
-            return i_ret;
-        }
-
-        memcpy( p_key, p_buffer + 4, DVD_DISCKEY_SIZE );
+        return i_ret;
     }
 
+    memcpy( p_key, key->KeyData, DVD_DISCKEY_SIZE );
+
 #elif defined( __QNXNTO__ )
 
     INIT_CPT( GPCMD_READ_DVD_STRUCTURE, DVD_DISCKEY_SIZE + 4 );
@@ -480,39 +445,22 @@
     memcpy( p_key, dvdbs.titleKeyValue, DVD_KEY_SIZE );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/2k/XP */
-    {
-        DWORD tmp;
-        uint8_t buffer[DVD_TITLE_KEY_LENGTH] = { 0 };
-        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
+    DWORD tmp;
+    uint8_t buffer[DVD_TITLE_KEY_LENGTH] = { 0 };
+    PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
 
-        key->KeyLength  = DVD_TITLE_KEY_LENGTH;
-        key->SessionId  = *pi_agid;
-        key->KeyType    = DvdTitleKey;
-        key->KeyFlags   = 0;
-        key->Parameters.TitleOffset.QuadPart = (LONGLONG) i_pos *
-                                               DVDCSS_BLOCK_SIZE;
+    key->KeyLength  = DVD_TITLE_KEY_LENGTH;
+    key->SessionId  = *pi_agid;
+    key->KeyType    = DvdTitleKey;
+    key->KeyFlags   = 0;
+    key->Parameters.TitleOffset.QuadPart = (LONGLONG) i_pos *
+                                           DVDCSS_BLOCK_SIZE;
 
-        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
-                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
+    i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
+            key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
 
-        memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
-    }
-    else
-    {
-        INIT_SSC( GPCMD_REPORT_KEY, 12 );
+    memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
 
-        ssc.CDBByte[ 2 ] = ( i_pos >> 24 ) & 0xff;
-        ssc.CDBByte[ 3 ] = ( i_pos >> 16 ) & 0xff;
-        ssc.CDBByte[ 4 ] = ( i_pos >>  8 ) & 0xff;
-        ssc.CDBByte[ 5 ] = ( i_pos       ) & 0xff;
-        ssc.CDBByte[ 10 ] = DVD_REPORT_TITLE_KEY | (*pi_agid << 6);
-
-        i_ret = WinSendSSC( i_fd, &ssc );
-
-        memcpy( p_key, p_buffer + 5, DVD_KEY_SIZE );
-    }
-
 #elif defined( __QNXNTO__ )
 
     INIT_CPT( GPCMD_REPORT_KEY, 12 );
@@ -613,27 +561,14 @@
     *pi_agid = dvdbs.grantID;
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/2k/XP */
-    {
-        ULONG id;
-        DWORD tmp = 0;
+    ULONG id;
+    DWORD tmp = 0;
 
-        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_START_SESSION,
-                        &tmp, 4, &id, sizeof( id ), &tmp, NULL ) ? 0 : -1;
+    i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_START_SESSION,
+                    &tmp, 4, &id, sizeof( id ), &tmp, NULL ) ? 0 : -1;
 
-        *pi_agid = id;
-    }
-    else
-    {
-        INIT_SSC( GPCMD_REPORT_KEY, 8 );
+    *pi_agid = id;
 
-        ssc.CDBByte[ 10 ] = DVD_REPORT_AGID | (*pi_agid << 6);
-
-        i_ret = WinSendSSC( i_fd, &ssc );
-
-        *pi_agid = p_buffer[ 7 ] >> 6;
-    }
-
 #elif defined( __QNXNTO__ )
 
     INIT_CPT( GPCMD_REPORT_KEY, 8 );
@@ -723,38 +658,25 @@
     memcpy( p_challenge, dvdbs.challengeKeyValue, DVD_CHALLENGE_SIZE );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/2k/XP */
-    {
-        DWORD tmp;
-        uint8_t buffer[DVD_CHALLENGE_KEY_LENGTH] = { 0 };
-        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
+    DWORD tmp;
+    uint8_t buffer[DVD_CHALLENGE_KEY_LENGTH] = { 0 };
+    PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
 
-        key->KeyLength  = DVD_CHALLENGE_KEY_LENGTH;
-        key->SessionId  = *pi_agid;
-        key->KeyType    = DvdChallengeKey;
-        key->KeyFlags   = 0;
+    key->KeyLength  = DVD_CHALLENGE_KEY_LENGTH;
+    key->SessionId  = *pi_agid;
+    key->KeyType    = DvdChallengeKey;
+    key->KeyFlags   = 0;
 
-        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
-                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
+    i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
+            key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
 
-        if( i_ret < 0 )
-        {
-            return i_ret;
-        }
-
-        memcpy( p_challenge, key->KeyData, DVD_CHALLENGE_SIZE );
-    }
-    else
+    if( i_ret < 0 )
     {
-        INIT_SSC( GPCMD_REPORT_KEY, 16 );
-
-        ssc.CDBByte[ 10 ] = DVD_REPORT_CHALLENGE | (*pi_agid << 6);
-
-        i_ret = WinSendSSC( i_fd, &ssc );
-
-        memcpy( p_challenge, p_buffer + 4, DVD_CHALLENGE_SIZE );
+        return i_ret;
     }
 
+    memcpy( p_challenge, key->KeyData, DVD_CHALLENGE_SIZE );
+
 #elif defined( __QNXNTO__ )
 
     INIT_CPT( GPCMD_REPORT_KEY, 16 );
@@ -842,42 +764,29 @@
     *pi_asf = dvdbs.successFlag;
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/2k/XP */
-    {
-        DWORD tmp;
-        uint8_t buffer[DVD_ASF_LENGTH] = { 0 };
-        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
-        PDVD_ASF keyData;
+    DWORD tmp;
+    uint8_t buffer[DVD_ASF_LENGTH] = { 0 };
+    PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
+    PDVD_ASF keyData;
 
-        key->KeyLength  = DVD_ASF_LENGTH;
-        key->KeyType    = DvdAsf;
-        key->KeyFlags   = 0;
+    key->KeyLength  = DVD_ASF_LENGTH;
+    key->KeyType    = DvdAsf;
+    key->KeyFlags   = 0;
 
-        keyData = (PDVD_ASF)key->KeyData;
-        keyData->SuccessFlag = *pi_asf;
+    keyData = (PDVD_ASF)key->KeyData;
+    keyData->SuccessFlag = *pi_asf;
 
-        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
-                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
+    i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
+            key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
 
-        if( i_ret < 0 )
-        {
-            return i_ret;
-        }
-
-        keyData = (PDVD_ASF)key->KeyData;
-        *pi_asf = keyData->SuccessFlag;
-    }
-    else
+    if( i_ret < 0 )
     {
-        INIT_SSC( GPCMD_REPORT_KEY, 8 );
-
-        ssc.CDBByte[ 10 ] = DVD_REPORT_ASF;
-
-        i_ret = WinSendSSC( i_fd, &ssc );
-
-        *pi_asf = p_buffer[ 7 ] & 1;
+        return i_ret;
     }
 
+    keyData = (PDVD_ASF)key->KeyData;
+    *pi_asf = keyData->SuccessFlag;
+
 #elif defined( __QNXNTO__ )
 
     INIT_CPT( GPCMD_REPORT_KEY, 8 );
@@ -967,33 +876,20 @@
     memcpy( p_key, dvdbs.key1Value, DVD_KEY_SIZE );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/2k/XP */
-    {
-        DWORD tmp;
-        uint8_t buffer[DVD_BUS_KEY_LENGTH] = { 0 };
-        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
+    DWORD tmp;
+    uint8_t buffer[DVD_BUS_KEY_LENGTH] = { 0 };
+    PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
 
-        key->KeyLength  = DVD_BUS_KEY_LENGTH;
-        key->SessionId  = *pi_agid;
-        key->KeyType    = DvdBusKey1;
-        key->KeyFlags   = 0;
+    key->KeyLength  = DVD_BUS_KEY_LENGTH;
+    key->SessionId  = *pi_agid;
+    key->KeyType    = DvdBusKey1;
+    key->KeyFlags   = 0;
 
-        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
-                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
+    i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
+            key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
 
-        memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
-    }
-    else
-    {
-        INIT_SSC( GPCMD_REPORT_KEY, 12 );
+    memcpy( p_key, key->KeyData, DVD_KEY_SIZE );
 
-        ssc.CDBByte[ 10 ] = DVD_REPORT_KEY1 | (*pi_agid << 6);
-
-        i_ret = WinSendSSC( i_fd, &ssc );
-
-        memcpy( p_key, p_buffer + 4, DVD_KEY_SIZE );
-    }
-
 #elif defined( __QNXNTO__ )
 
     INIT_CPT( GPCMD_REPORT_KEY, 12 );
@@ -1073,30 +969,11 @@
     i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/2k/XP */
-    {
-        DWORD tmp;
+    DWORD tmp;
 
-        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_END_SESSION,
-                    pi_agid, sizeof( *pi_agid ), NULL, 0, &tmp, NULL ) ? 0 : -1;
-    }
-    else
-    {
-#if defined( __MINGW32__ )
-        INIT_SSC( GPCMD_REPORT_KEY, 0 );
-#else
-        INIT_SSC( GPCMD_REPORT_KEY, 1 );
+    i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_END_SESSION,
+                pi_agid, sizeof( *pi_agid ), NULL, 0, &tmp, NULL ) ? 0 : -1;
 
-        ssc.SRB_BufLen    = 0;
-        ssc.CDBByte[ 8 ]  = 0;
-        ssc.CDBByte[ 9 ]  = 0;
-#endif
-
-        ssc.CDBByte[ 10 ] = DVDCSS_INVALIDATE_AGID | (*pi_agid << 6);
-
-        i_ret = WinSendSSC( i_fd, &ssc );
-    }
-
 #elif defined( __QNXNTO__ )
 
     INIT_CPT( GPCMD_REPORT_KEY, 0 );
@@ -1189,34 +1066,20 @@
     i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/2k/XP */
-    {
-        DWORD tmp;
-        uint8_t buffer[DVD_CHALLENGE_KEY_LENGTH] = { 0 };
-        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
+    DWORD tmp;
+    uint8_t buffer[DVD_CHALLENGE_KEY_LENGTH] = { 0 };
+    PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
 
-        key->KeyLength  = DVD_CHALLENGE_KEY_LENGTH;
-        key->SessionId  = *pi_agid;
-        key->KeyType    = DvdChallengeKey;
-        key->KeyFlags   = 0;
+    key->KeyLength  = DVD_CHALLENGE_KEY_LENGTH;
+    key->SessionId  = *pi_agid;
+    key->KeyType    = DvdChallengeKey;
+    key->KeyFlags   = 0;
 
-        memcpy( key->KeyData, p_challenge, DVD_CHALLENGE_SIZE );
+    memcpy( key->KeyData, p_challenge, DVD_CHALLENGE_SIZE );
 
-        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key,
-                 key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
-    }
-    else
-    {
-        INIT_SSC( GPCMD_SEND_KEY, 16 );
+    i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key,
+             key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
 
-        ssc.CDBByte[ 10 ] = DVD_SEND_CHALLENGE | (*pi_agid << 6);
-
-        p_buffer[ 1 ] = 0xe;
-        memcpy( p_buffer + 4, p_challenge, DVD_CHALLENGE_SIZE );
-
-        i_ret = WinSendSSC( i_fd, &ssc );
-    }
-
 #elif defined( __QNXNTO__ )
 
     INIT_CPT( GPCMD_SEND_KEY, 16 );
@@ -1312,34 +1175,20 @@
     i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/2k/XP */
-    {
-        DWORD tmp;
-        uint8_t buffer[DVD_BUS_KEY_LENGTH] = { 0 };
-        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
+    DWORD tmp;
+    uint8_t buffer[DVD_BUS_KEY_LENGTH] = { 0 };
+    PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
 
-        key->KeyLength  = DVD_BUS_KEY_LENGTH;
-        key->SessionId  = *pi_agid;
-        key->KeyType    = DvdBusKey2;
-        key->KeyFlags   = 0;
+    key->KeyLength  = DVD_BUS_KEY_LENGTH;
+    key->SessionId  = *pi_agid;
+    key->KeyType    = DvdBusKey2;
+    key->KeyFlags   = 0;
 
-        memcpy( key->KeyData, p_key, DVD_KEY_SIZE );
+    memcpy( key->KeyData, p_key, DVD_KEY_SIZE );
 
-        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key,
-                 key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
-    }
-    else
-    {
-        INIT_SSC( GPCMD_SEND_KEY, 12 );
+    i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_SEND_KEY, key,
+             key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
 
-        ssc.CDBByte[ 10 ] = DVD_SEND_KEY2 | (*pi_agid << 6);
-
-        p_buffer[ 1 ] = 0xa;
-        memcpy( p_buffer + 4, p_key, DVD_KEY_SIZE );
-
-        i_ret = WinSendSSC( i_fd, &ssc );
-    }
-
 #elif defined( __QNXNTO__ )
 
     INIT_CPT( GPCMD_SEND_KEY, 12 );
@@ -1443,43 +1292,28 @@
     *p_scheme = dvdbs.rpcScheme;
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/2k/XP */
-    {
-        DWORD tmp;
-        uint8_t buffer[DVD_RPC_KEY_LENGTH] = { 0 };
-        PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
-        PDVD_RPC_KEY keyData;
+    DWORD tmp;
+    uint8_t buffer[DVD_RPC_KEY_LENGTH] = { 0 };
+    PDVD_COPY_PROTECT_KEY key = (PDVD_COPY_PROTECT_KEY) &buffer;
+    PDVD_RPC_KEY keyData;
 
-        key->KeyLength  = DVD_RPC_KEY_LENGTH;
-        key->KeyType    = DvdGetRpcKey;
-        key->KeyFlags   = 0;
+    key->KeyLength  = DVD_RPC_KEY_LENGTH;
+    key->KeyType    = DvdGetRpcKey;
+    key->KeyFlags   = 0;
 
-        i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
-                key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
+    i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key,
+            key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
 
-        if( i_ret < 0 )
-        {
-            return i_ret;
-        }
-
-        keyData = (PDVD_RPC_KEY)key->KeyData;
-        *p_type = keyData->TypeCode;
-        *p_mask = keyData->RegionMask;
-        *p_scheme = keyData->RpcScheme;
-    }
-    else
+    if( i_ret < 0 )
     {
-        INIT_SSC( GPCMD_REPORT_KEY, 8 );
-
-        ssc.CDBByte[ 10 ] = DVD_REPORT_RPC;
-
-        i_ret = WinSendSSC( i_fd, &ssc );
-
-        *p_type = p_buffer[ 4 ] >> 6;
-        *p_mask = p_buffer[ 5 ];
-        *p_scheme = p_buffer[ 6 ];
+        return i_ret;
     }
 
+    keyData = (PDVD_RPC_KEY)key->KeyData;
+    *p_type = keyData->TypeCode;
+    *p_mask = keyData->RegionMask;
+    *p_scheme = keyData->RpcScheme;
+
 #elif defined( __QNXNTO__ )
 
     INIT_CPT( GPCMD_REPORT_KEY, 8 );
@@ -1676,67 +1510,6 @@
     p_sptd->CdbLength = 12;
 
     p_sptd->TimeOutValue = 2;
-}
-
-/*****************************************************************************
- * WinInitSSC: initialize a ssc structure for the win32 aspi layer
- *****************************************************************************
- * This function initializes a ssc raw device command structure for future
- * use, either a read command or a write command.
- *****************************************************************************/
-static void WinInitSSC( struct SRB_ExecSCSICmd *p_ssc, int i_type )
-{
-    memset( p_ssc->SRB_BufPointer, 0, p_ssc->SRB_BufLen );
-
-    switch( i_type )
-    {
-        case GPCMD_SEND_KEY:
-            p_ssc->SRB_Flags = SRB_DIR_OUT;
-            break;
-
-        case GPCMD_READ_DVD_STRUCTURE:
-        case GPCMD_REPORT_KEY:
-            p_ssc->SRB_Flags = SRB_DIR_IN;
-            break;
-    }
-
-    p_ssc->SRB_Cmd      = SC_EXEC_SCSI_CMD;
-    p_ssc->SRB_Flags    |= SRB_EVENT_NOTIFY;
-
-    p_ssc->CDBByte[ 0 ] = i_type;
-
-    p_ssc->CDBByte[ 8 ] = (uint8_t)(p_ssc->SRB_BufLen >> 8) & 0xff;
-    p_ssc->CDBByte[ 9 ] = (uint8_t) p_ssc->SRB_BufLen       & 0xff;
-    p_ssc->SRB_CDBLen   = 12;
-
-    p_ssc->SRB_SenseLen = SENSE_LEN;
-}
-
-/*****************************************************************************
- * WinSendSSC: send a ssc structure to the aspi layer
- *****************************************************************************/
-static int WinSendSSC( int i_fd, struct SRB_ExecSCSICmd *p_ssc )
-{
-    HANDLE hEvent = NULL;
-    struct w32_aspidev *fd = (struct w32_aspidev *) i_fd;
-
-    hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
-    if( hEvent == NULL )
-    {
-        return -1;
-    }
-
-    p_ssc->SRB_PostProc  = hEvent;
-    p_ssc->SRB_HaId      = LOBYTE( fd->i_sid );
-    p_ssc->SRB_Target    = HIBYTE( fd->i_sid );
-
-    ResetEvent( hEvent );
-    if( fd->lpSendCommand( (void*) p_ssc ) == SS_PENDING )
-        WaitForSingleObject( hEvent, INFINITE );
-
-    CloseHandle( hEvent );
-
-    return p_ssc->SRB_Status == SS_COMP ? 0 : -1;
 }
 #endif
 
--- a/src/ioctl.h
+++ b/src/ioctl.h
@@ -96,12 +96,6 @@
                       (SPTD), sizeof( SCSI_PASS_THROUGH_DIRECT ), \
                       (SPTD), sizeof( SCSI_PASS_THROUGH_DIRECT ), \
                       (TMP), NULL ) ? 0 : -1)
-#define INIT_SSC( TYPE, SIZE ) \
-    struct SRB_ExecSCSICmd ssc = { 0 }; \
-    uint8_t p_buffer[ (SIZE)+1 ]; \
-    ssc.SRB_BufPointer = (unsigned char *)p_buffer; \
-    ssc.SRB_BufLen = (SIZE); \
-    WinInitSSC( &ssc, (TYPE) );
 #endif
 
 /*****************************************************************************
@@ -291,92 +285,6 @@
     ULONG SenseInfoOffset;
     UCHAR Cdb[16];
 } SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
-
-/*****************************************************************************
- * win32 aspi specific
- *****************************************************************************/
-
-typedef DWORD (CALLBACK *GETASPI32SUPPORTINFO)(VOID);
-typedef DWORD (CALLBACK *SENDASPI32COMMAND)(LPVOID);
-
-#define WIN2K               ( GetVersion() < 0x80000000 )
-#define ASPI_HAID           0
-#define ASPI_TARGET         0
-#define DTYPE_CDROM         0x05
-
-#define SENSE_LEN           0x0E
-#define SC_GET_DEV_TYPE     0x01
-#define SC_EXEC_SCSI_CMD    0x02
-#define SC_GET_DISK_INFO    0x06
-#define SS_COMP             0x01
-#define SS_PENDING          0x00
-#define SS_NO_ADAPTERS      0xE8
-#define SRB_DIR_IN          0x08
-#define SRB_DIR_OUT         0x10
-#define SRB_EVENT_NOTIFY    0x40
-
-struct w32_aspidev
-{
-    long  hASPI;
-    short i_sid;
-    int   i_blocks;
-    SENDASPI32COMMAND lpSendCommand;
-};
-
-#pragma pack(1)
-
-struct SRB_GetDiskInfo
-{
-    unsigned char   SRB_Cmd;
-    unsigned char   SRB_Status;
-    unsigned char   SRB_HaId;
-    unsigned char   SRB_Flags;
-    unsigned long   SRB_Hdr_Rsvd;
-    unsigned char   SRB_Target;
-    unsigned char   SRB_Lun;
-    unsigned char   SRB_DriveFlags;
-    unsigned char   SRB_Int13HDriveInfo;
-    unsigned char   SRB_Heads;
-    unsigned char   SRB_Sectors;
-    unsigned char   SRB_Rsvd1[22];
-};
-
-struct SRB_GDEVBlock
-{
-    unsigned char SRB_Cmd;
-    unsigned char SRB_Status;
-    unsigned char SRB_HaId;
-    unsigned char SRB_Flags;
-    unsigned long SRB_Hdr_Rsvd;
-    unsigned char SRB_Target;
-    unsigned char SRB_Lun;
-    unsigned char SRB_DeviceType;
-    unsigned char SRB_Rsvd1;
-};
-
-struct SRB_ExecSCSICmd
-{
-    unsigned char   SRB_Cmd;
-    unsigned char   SRB_Status;
-    unsigned char   SRB_HaId;
-    unsigned char   SRB_Flags;
-    unsigned long   SRB_Hdr_Rsvd;
-    unsigned char   SRB_Target;
-    unsigned char   SRB_Lun;
-    unsigned short  SRB_Rsvd1;
-    unsigned long   SRB_BufLen;
-    unsigned char   *SRB_BufPointer;
-    unsigned char   SRB_SenseLen;
-    unsigned char   SRB_CDBLen;
-    unsigned char   SRB_HaStat;
-    unsigned char   SRB_TargStat;
-    unsigned long   *SRB_PostProc;
-    unsigned char   SRB_Rsvd2[20];
-    unsigned char   CDBByte[16];
-    unsigned char   SenseArea[SENSE_LEN+2];
-};
-
-#pragma pack()
 
 #endif
 
--- a/src/libdvdcss.c
+++ b/src/libdvdcss.c
@@ -30,8 +30,8 @@
  * device without having to bother about the decryption. The important features
  * are:
  * \li portability: Currently supported platforms are GNU/Linux, FreeBSD,
- *     NetBSD, OpenBSD, BeOS, Mac OS X, Solaris, OS/2, Windows 98 SE
- *     (with IE 5.0) or later, and Windows NT 4.0 (with IE 5.0) or later.
+ *     NetBSD, OpenBSD, BeOS, Mac OS X, Solaris, OS/2, and Windows NT 4.0
+ *     SP4 (with IE 5.0) or later.
  * \li adaptability: Unlike most similar projects, libdvdcss does not require
  *     the region of your drive to be set and will try its best to read from
  *     the disc even in the case of a region mismatch.
--- a/test/dvd_region.c
+++ b/test/dvd_region.c
@@ -94,28 +94,14 @@
     i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/2k/XP */
-    {
-        INIT_SPTD( GPCMD_SEND_KEY, 8 );
+    INIT_SPTD( GPCMD_SEND_KEY, 8 );
 
-        sptd.Cdb[ 10 ] = DVD_SEND_RPC;
+    sptd.Cdb[ 10 ] = DVD_SEND_RPC;
 
-        p_buffer[ 1 ] = 6;
-        p_buffer[ 4 ] = i_pdrc;
+    p_buffer[ 1 ] = 6;
+    p_buffer[ 4 ] = i_pdrc;
 
-        i_ret = SEND_SPTD( i_fd, &sptd, &tmp );
-    }
-    else
-    {
-        INIT_SSC( GPCMD_SEND_KEY, 8 );
-
-        ssc.CDBByte[ 10 ] = DVD_SEND_RPC;
-
-        p_buffer[ 1 ] = 6;
-        p_buffer[ 4 ] = i_pdrc;
-
-        i_ret = WinSendSSC( i_fd, &ssc );
-    }
+    i_ret = SEND_SPTD( i_fd, &sptd, &tmp );
 
 #elif defined( __QNXNTO__ )