Commit 95671de3 authored by Gildas Bazin's avatar Gildas Bazin

* src/css.c, src/device.c, src/ioctl.[ch]: We don't need to be in administrator mode

anymore to authenticate the drive on Windows NT/2k/XP. As a result any user can now
play a DVD on these OSs :)
* src/ioctl.c: fixed ioctl_ReadTitleKey which wasn't working on Windows NT/2k/XP.
Because of this bug, the disc and key methods for key decryption where not working.
parent 3adf615d
......@@ -58,3 +58,7 @@ N: German Tischler
E: tanis@gaspode.franken.de
D: FreeBSD DVD input patch
N: Gildas Bazin
E: gbazin@netcourrier.com
C: gbazin
D: various fixes to the Win32 port
......@@ -2,7 +2,7 @@
* css.c: Functions for DVD authentication and descrambling
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: css.c,v 1.15 2002/08/10 21:19:55 sam Exp $
* $Id: css.c,v 1.16 2002/10/10 12:44:28 gbazin Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
* Hkan Hjort <d95hjort@dtek.chalmers.se>
......@@ -83,13 +83,7 @@ int _dvdcss_test( dvdcss_t dvdcss )
/* Since it's the first ioctl we try to issue, we add a notice */
_dvdcss_error( dvdcss, "css error: ioctl_ReadCopyright failed, "
"make sure there is a DVD in the drive, and that "
"you have used the correct device node."
#if defined( WIN32 )
"\nAlso note that if you are using Windows NT/2000/XP "
"you need to have administrator priviledges to be able "
"to use ioctls."
#endif
);
"you have used the correct device node." );
return i_ret;
}
......
......@@ -2,7 +2,7 @@
* device.h: DVD device access
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
* $Id: device.c,v 1.3 2002/08/10 17:42:09 sam Exp $
* $Id: device.c,v 1.4 2002/10/10 12:44:28 gbazin Exp $
*
* Authors: Stphane Borel <stef@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -169,10 +169,12 @@ int _dvdcss_open ( dvdcss_t dvdcss )
char psz_dvd[7];
_snprintf( psz_dvd, 7, "\\\\.\\%c:", psz_device[0] );
/* To have access to ioctls, we need read and write access to the
* device. This is only allowed if you have administrator priviledges
* so we allow for a fallback method where ioctls are not available but
* we at least have read access to the device.
/* To work around an M$ bug in IOCTL_DVD_READ_STRUCTURE, we need read
* _and_ write access to the device (so we can make SCSI Pass Through
* Requests). Unfortunately this is only allowed if you have
* administrator priviledges so we allow for a fallback method with
* only read access to the device (in this case ioctl_ReadCopyright()
* won't send back the right result).
* (See Microsoft Q241374: Read and Write Access Required for SCSI
* Pass Through Requests) */
(HANDLE) dvdcss->i_fd =
......
......@@ -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 Siebrger <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 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
*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;
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. */
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 ) );
sptd.Length = sizeof( SCSI_PASS_THROUGH_DIRECT );
sptd.CdbLength = 12;
......@@ -241,7 +244,30 @@ int ioctl_ReadCopyright( int i_fd, int i_layer, int *pi_copyright )
&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 @@ int ioctl_ReadDiscKey( int i_fd, int *pi_agid, u8 *p_key )
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 @@ int ioctl_ReadTitleKey( int i_fd, int *pi_agid, int i_pos, u8 *p_key )
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 @@ int ioctl_ReadTitleKey( int i_fd, int *pi_agid, int i_pos, u8 *p_key )
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 @@ int ioctl_ReportAgid( int i_fd, int *pi_agid )
*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 @@ int ioctl_ReportChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
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 @@ int ioctl_ReportASF( int i_fd, int *pi_remove_me, int *pi_asf )
*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 @@ int ioctl_ReportKey1( int i_fd, int *pi_agid, u8 *p_key )
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 @@ int ioctl_InvalidateAgid( int i_fd, int *pi_agid )
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 @@ int ioctl_SendChallenge( int i_fd, int *pi_agid, u8 *p_challenge )
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 @@ int ioctl_SendKey2( int i_fd, int *pi_agid, u8 *p_key )
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 @@ int ioctl_ReportRPC( int i_fd, int *p_type, int *p_mask, int *p_scheme )
*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 @@ int ioctl_ReportRPC( int i_fd, int *p_type, int *p_mask, int *p_scheme )
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 @@ static void QNXInitCPT( CAM_PASS_THRU * p_cpt, int i_type )
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
......
......@@ -2,7 +2,7 @@
* ioctl.h: DVD ioctl replacement function
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: ioctl.h,v 1.7 2002/08/10 17:42:09 sam Exp $
* $Id: ioctl.h,v 1.8 2002/10/10 12:44:28 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -188,7 +188,7 @@ typedef union dvd_authinfo dvd_authinfo;
#define IOCTL_DVD_END_SESSION CTL_CODE(FILE_DEVICE_DVD, 0x0403, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_DVD_GET_REGION CTL_CODE(FILE_DEVICE_DVD, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_DVD_SEND_KEY2 CTL_CODE(FILE_DEVICE_DVD, 0x0406, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_DVD_READ_STRUCTURE CTL_CODE(FILE_DEVICE_DVD, 0x0450, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(FILE_DEVICE_CONTROLLER, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define DVD_CHALLENGE_KEY_LENGTH (12 + sizeof(DVD_COPY_PROTECT_KEY))
......@@ -203,6 +203,28 @@ typedef union dvd_authinfo dvd_authinfo;
typedef ULONG DVD_SESSION_ID, *PDVD_SESSION_ID;
typedef enum DVD_STRUCTURE_FORMAT {
DvdPhysicalDescriptor,
DvdCopyrightDescriptor,
DvdDiskKeyDescriptor,
DvdBCADescriptor,
DvdManufacturerDescriptor,
DvdMaxDescriptor
} DVD_STRUCTURE_FORMAT, *PDVD_STRUCTURE_FORMAT;
typedef struct DVD_READ_STRUCTURE {
LARGE_INTEGER BlockByteOffset;
DVD_STRUCTURE_FORMAT Format;
DVD_SESSION_ID SessionId;
UCHAR LayerNumber;
} DVD_READ_STRUCTURE, *PDVD_READ_STRUCTURE;
typedef struct _DVD_COPYRIGHT_DESCRIPTOR {
UCHAR CopyrightProtectionType;
UCHAR RegionManagementInformation;
USHORT Reserved;
} DVD_COPYRIGHT_DESCRIPTOR, *PDVD_COPYRIGHT_DESCRIPTOR;
typedef enum
{
DvdChallengeKey = 0x01,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment