--- a/src/ioctl.c
+++ b/src/ioctl.c
@@ -2,7 +2,7 @@
  * ioctl.c: DVD ioctl replacement function
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: ioctl.c,v 1.13 2002/08/10 17:42:09 sam Exp $
+ * $Id: ioctl.c,v 1.14 2002/10/10 12:44:28 gbazin Exp $
  *
  * Authors: Markus Kuespert <ltlBeBoy@beosmail.com>
  *          Samuel Hocevar <sam@zoy.org>
@@ -11,6 +11,7 @@
  *          Eugenio Jarosiewicz <ej0@cise.ufl.edu>
  *          David Siebörger <drs-videolan@rucus.ru.ac.za>
  *          Alex Strelnikov <lelik@os2.ru>
+ *          Gildas Bazin <gbazin@netcourrier.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -210,18 +211,20 @@
     *pi_copyright = dvdbs.copyrightProtectionSystemType;
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/Win2000/Whistler */
+    if( WIN2K ) /* NT/2k/XP */
     {
         DWORD tmp;
         u8 p_buffer[ 8 ];
         SCSI_PASS_THROUGH_DIRECT sptd;
 
+        /*  When using IOCTL_DVD_READ_STRUCTURE and 
+            DVD_COPYRIGHT_DESCRIPTOR, CopyrightProtectionType
+            seems to be always 6 ???
+            To work around this M$ bug we try to send a raw scsi command
+            instead (if we've got enough privileges to do so). */
+
         memset( &sptd, 0, sizeof( sptd ) );
         memset( &p_buffer, 0, sizeof( p_buffer ) );
-   
-        /*  When using IOCTL_DVD_READ_STRUCTURE and 
-            DVD_COPYRIGHT_DESCRIPTOR, CopyrightProtectionType
-            is always 6. So we send a raw scsi command instead. */
 
         sptd.Length             = sizeof( SCSI_PASS_THROUGH_DIRECT );
         sptd.CdbLength          = 12;
@@ -241,7 +244,30 @@
                              &sptd, sizeof( SCSI_PASS_THROUGH_DIRECT ),
                              &tmp, NULL ) ? 0 : -1;
 
-        *pi_copyright = p_buffer[ 4 ];
+        if( i_ret == 0 )
+        {
+            *pi_copyright = p_buffer[ 4 ];
+        }
+        else
+        {
+            /* We don't have the privileges to send a SCSI_PASS_THROUGH
+               command, let's try the buggy IOCTL_DVD_READ_STRUCTURE anyway */
+
+            DVD_READ_STRUCTURE dvd_struct;
+            DVD_COPYRIGHT_DESCRIPTOR dvd_descr;
+
+            memset( &dvd_struct, 0, sizeof( DVD_READ_STRUCTURE ) );
+
+            dvd_struct.Format = DvdCopyrightDescriptor;
+            dvd_struct.LayerNumber = i_layer;
+
+            i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_STRUCTURE,
+                                 &dvd_struct, sizeof(DVD_READ_STRUCTURE),
+                                 &dvd_descr, sizeof(DVD_COPYRIGHT_DESCRIPTOR),
+                                 &tmp, NULL ) ? 0 : -1;
+
+            *pi_copyright = dvd_descr.CopyrightProtectionType;
+        }
     }
     else
     {
@@ -383,7 +409,7 @@
     memcpy( p_key, dvdbs.discKeyStructures, DVD_DISCKEY_SIZE );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/Win2000/Whistler */
+    if( WIN2K ) /* NT/2k/XP */
     {
         DWORD tmp;
         u8 buffer[DVD_DISK_KEY_LENGTH];
@@ -551,7 +577,7 @@
     memcpy( p_key, dvdbs.titleKeyValue, DVD_KEY_SIZE );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/Win2000/Whistler */
+    if( WIN2K ) /* NT/2k/XP */
     {
         DWORD tmp;
         u8 buffer[DVD_BUS_KEY_LENGTH];
@@ -563,7 +589,8 @@
         key->SessionId  = *pi_agid;
         key->KeyType    = DvdTitleKey;
         key->KeyFlags   = 0;
-        key->Parameters.TitleOffset.QuadPart = (LONGLONG) i_pos;
+        key->Parameters.TitleOffset.QuadPart = (LONGLONG) i_pos *
+                                                   2048 /*DVDCSS_BLOCK_SIZE*/;
 
         i_ret = DeviceIoControl( (HANDLE) i_fd, IOCTL_DVD_READ_KEY, key, 
                 key->KeyLength, key, key->KeyLength, &tmp, NULL ) ? 0 : -1;
@@ -696,7 +723,7 @@
     *pi_agid = dvdbs.grantID;
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/Win2000/Whistler */
+    if( WIN2K ) /* NT/2k/XP */
     {
         ULONG id;
         DWORD tmp;
@@ -817,7 +844,7 @@
     memcpy( p_challenge, dvdbs.challengeKeyValue, DVD_CHALLENGE_SIZE );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/Win2000/Whistler */
+    if( WIN2K ) /* NT/2k/XP */
     {
         DWORD tmp;
         u8 buffer[DVD_CHALLENGE_KEY_LENGTH];
@@ -949,7 +976,7 @@
     *pi_asf = dvdbs.successFlag;
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/Win2000/Whistler */
+    if( WIN2K ) /* NT/2k/XP */
     {
         DWORD tmp;
         u8 buffer[DVD_ASF_LENGTH];
@@ -1084,7 +1111,7 @@
     memcpy( p_key, dvdbs.key1Value, DVD_KEY_SIZE );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/Win2000/Whistler */
+    if( WIN2K ) /* NT/2k/XP */
     {
         DWORD tmp;
         u8 buffer[DVD_BUS_KEY_LENGTH];
@@ -1201,7 +1228,7 @@
     i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/Win2000/Whistler */
+    if( WIN2K ) /* NT/2k/XP */
     {
         DWORD tmp;
 
@@ -1329,7 +1356,7 @@
     i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/Win2000/Whistler */
+    if( WIN2K ) /* NT/2k/XP */
     {
         DWORD tmp;
         u8 buffer[DVD_CHALLENGE_KEY_LENGTH];
@@ -1466,7 +1493,7 @@
     i_ret = ioctl( i_fd, DKIOCDVDSENDKEY, &dvd );
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/Win2000/Whistler */
+    if( WIN2K ) /* NT/2k/XP */
     {
         DWORD tmp;
         u8 buffer[DVD_BUS_KEY_LENGTH];
@@ -1612,7 +1639,7 @@
     *p_scheme = dvdbs.rpcScheme;
 
 #elif defined( WIN32 )
-    if( WIN2K ) /* NT/Win2000/Whistler */
+    if( WIN2K ) /* NT/2k/XP */
     {
         DWORD tmp;
         u8 buffer[ DVD_REGION_LENGTH ];
@@ -1624,19 +1651,19 @@
                 region, DVD_REGION_LENGTH, &tmp, NULL ) ? 0 : -1;
 
         /* Someone who has the headers should correct all this. */
-	/* Use the IOCTL_SCSI_PASS_THROUGH_DIRECT so we get the real
-	 * values of theses entities?  */
+        /* Use the IOCTL_SCSI_PASS_THROUGH_DIRECT so we get the real
+         * values of theses entities?  */
         if(region->SystemRegion != 0) {
-	    *p_type = region->ResetCount > 1 ? 1 : 3 - region->ResetCount;
-	    *p_mask =  0xff ^ (1 << (region->SystemRegion - 1));
-	    *p_scheme = 1;
-	}
-	else
-	{
-	    *p_type = 0;  /* ?? */
-	    *p_mask = 0xff;
-	    *p_scheme = 1; /* ?? */
-	}
+            *p_type = region->ResetCount > 1 ? 1 : 3 - region->ResetCount;
+            *p_mask =  0xff ^ (1 << (region->SystemRegion - 1));
+            *p_scheme = 1;
+        }
+        else
+        {
+            *p_type = 0;  /* ?? */
+            *p_mask = 0xff;
+            *p_scheme = 1; /* ?? */
+        }
     }
     else
     {
@@ -1878,7 +1905,7 @@
     p_cpt->cam_cdb[ 9 ] =  p_cpt->cam_dxfer_len       & 0xff;
     p_cpt->cam_cdb_len = 12;
 
-	p_cpt->cam_timeout = CAM_TIME_DEFAULT;
+    p_cpt->cam_timeout = CAM_TIME_DEFAULT;
 }
 #endif