diff --git a/reactos/drivers/storage/cdrom/cdrom.c b/reactos/drivers/storage/cdrom/cdrom.c index af7341209dd..a202109e83c 100644 --- a/reactos/drivers/storage/cdrom/cdrom.c +++ b/reactos/drivers/storage/cdrom/cdrom.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: cdrom.c,v 1.14 2002/09/08 10:22:22 chorns Exp $ +/* $Id: cdrom.c,v 1.15 2002/09/15 22:19:16 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -512,7 +512,45 @@ CdromClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, return(STATUS_SUCCESS); } +/********************************************************************** + * NAME + * CdromClassReadTocEntry + * + * ARGUMENTS: + * DeviceObject + * TrackNo + * Buffer + * Length + * + * RETURNS: + * Status. + */ +static NTSTATUS +CdromClassReadTocEntry(PDEVICE_OBJECT DeviceObject, UINT TrackNo, PVOID Buffer, UINT Length) +{ + PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + SCSI_REQUEST_BLOCK Srb; + PCDB Cdb; + + RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK)); + Srb.CdbLength = 10; + Srb.TimeOutValue = DeviceExtension->TimeOutValue; + + Cdb = (PCDB)Srb.Cdb; + Cdb->READ_TOC.OperationCode = SCSIOP_READ_TOC; + Cdb->READ_TOC.StartingTrack = TrackNo; + Cdb->READ_TOC.Format = 0; + Cdb->READ_TOC.AllocationLength[0] = Length >> 8; + Cdb->READ_TOC.AllocationLength[1] = Length & 0xff; + Cdb->READ_TOC.Msf = 1; + + return ScsiClassSendSrbSynchronous(DeviceObject, + &Srb, + Buffer, + Length, + FALSE); +} /********************************************************************** * NAME EXPORTED @@ -586,7 +624,43 @@ CdromClassDeviceControl(IN PDEVICE_OBJECT DeviceObject, } } break; + case IOCTL_CDROM_READ_TOC: + DPRINT("IOCTL_CDROM_READ_TOC\n"); + if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CDROM_TOC)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + PCDROM_TOC TocBuffer; + USHORT Length; + TocBuffer = Irp->AssociatedIrp.SystemBuffer; + + /* First read the lead out */ + Length = 4 + sizeof(TRACK_DATA); + Status = CdromClassReadTocEntry(DeviceObject, 0xaa, TocBuffer, Length); + + if (NT_SUCCESS(Status)) + { + if (TocBuffer->FirstTrack == 0xaa) + { + /* there is an empty cd */ + Information = Length; + } + else + { + /* read the toc */ + Length = 4 + sizeof(TRACK_DATA) * (TocBuffer->LastTrack - TocBuffer->FirstTrack + 2); + Status = CdromClassReadTocEntry(DeviceObject, TocBuffer->FirstTrack, TocBuffer, Length); + if (NT_SUCCESS(Status)) + { + Information = Length; + } + } + } + } + break; default: /* Call the common device control function */ return(ScsiClassDeviceControl(DeviceObject, Irp)); diff --git a/reactos/include/ntos/cdrom.h b/reactos/include/ntos/cdrom.h index badc7f4a941..3dc5c8d3afb 100644 --- a/reactos/include/ntos/cdrom.h +++ b/reactos/include/ntos/cdrom.h @@ -1,4 +1,4 @@ -/* $Id: cdrom.h,v 1.1 2002/04/10 17:00:52 ekohl Exp $ +/* $Id: cdrom.h,v 1.2 2002/09/15 22:19:16 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -12,8 +12,30 @@ #ifndef __INCLUDE_NTOS_CDROM_H #define __INCLUDE_NTOS_CDROM_H +#define IOCTL_CDROM_READ_TOC CTL_CODE(FILE_DEVICE_CD_ROM, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(FILE_DEVICE_CD_ROM, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS) + +#define MAXIMUM_NUMBER_TRACKS 100 +#define MAXIMUM_CDROM_SIZE 804 + +typedef struct _TRACK_DATA { + UCHAR Reserved; + UCHAR Control : 4; + UCHAR Adr : 4; + UCHAR TrackNumber; + UCHAR Reserved1; + UCHAR Address[4]; +} TRACK_DATA, *PTRACK_DATA; + +typedef struct _CDROM_TOC { + UCHAR Length[2]; + UCHAR FirstTrack; + UCHAR LastTrack; + TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]; +} CDROM_TOC, *PCDROM_TOC; + +#define CDROM_TOC_SIZE sizeof(CDROM_TOC) -#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(FILE_DEVICE_CD_ROM, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS) #endif /* __INCLUDE_NTOS_CDROM_H */