2023-12-07 20:30:48 +01:00
/*
* 86 Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus .
*
* This file is part of the 86 Box distribution .
*
* Win32 CD - ROM support via IOCTL .
*
*
*
* Authors : TheCollector1995 , < mariogplayer @ gmail . com > ,
* Miran Grca , < mgrca8 @ gmail . com >
*
* Copyright 2023 TheCollector1995 .
* Copyright 2023 Miran Grca .
*/
# define UNICODE
# define BITMAP WINDOWS_BITMAP
# include <windows.h>
# include <windowsx.h>
# undef BITMAP
2024-05-19 21:17:57 +02:00
# include <inttypes.h>
2023-12-07 20:30:48 +01:00
# include <io.h>
# include "ntddcdrm.h"
# include "ntddscsi.h"
2024-05-19 21:17:57 +02:00
# include <stdarg.h>
2023-12-07 20:30:48 +01:00
# include <stdio.h>
2024-05-19 21:17:57 +02:00
# include <stdint.h>
# include <string.h>
# include <stdlib.h>
# include <wchar.h>
# define HAVE_STDARG_H
2023-12-07 20:30:48 +01:00
# include <86box/86box.h>
# include <86box/scsi_device.h>
# include <86box/cdrom.h>
# include <86box/plat_unused.h>
# include <86box/plat_cdrom.h>
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
there is a seeming 2 seconds in which audio plays but counter does not move , while a data track before audio jumps to 2 seconds before the actual start
of the audio while audio still plays . With an absolute conversion , the counter is fine . */
# define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
2024-11-25 21:23:28 +01:00
typedef struct win_cdrom_ioctl_t {
int toc_valid ;
uint8_t cur_toc [ 65536 ] ;
CDROM_READ_TOC_EX cur_read_toc_ex ;
int blocks_num ;
uint8_t cur_rti [ 65536 ] ;
HANDLE handle ;
WCHAR path [ 256 ] ;
WCHAR old_path [ 256 ] ;
} win_cdrom_ioctl_t ;
2024-05-19 21:17:57 +02:00
# ifdef ENABLE_WIN_CDROM_IOCTL_LOG
int win_cdrom_ioctl_do_log = ENABLE_WIN_CDROM_IOCTL_LOG ;
void
win_cdrom_ioctl_log ( const char * fmt , . . . )
{
va_list ap ;
if ( win_cdrom_ioctl_do_log ) {
va_start ( ap , fmt ) ;
pclog_ex ( fmt , ap ) ;
va_end ( ap ) ;
}
}
# else
# define win_cdrom_ioctl_log(fmt, ...)
# endif
2024-05-18 22:37:49 +02:00
static int
2024-11-25 21:23:28 +01:00
plat_cdrom_open ( void * local )
2024-05-18 22:37:49 +02:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
2024-05-18 22:37:49 +02:00
2024-11-25 21:23:28 +01:00
plat_cdrom_close ( local ) ;
2024-05-20 01:57:15 +02:00
2024-11-25 21:23:28 +01:00
ioctl - > handle = CreateFileW ( ( LPCWSTR ) ioctl - > path , GENERIC_READ | GENERIC_WRITE ,
FILE_SHARE_READ | FILE_SHARE_WRITE , NULL , OPEN_EXISTING , 0 , NULL ) ;
win_cdrom_ioctl_log ( " handle=%p, error=%x \n " , ioctl - > handle , ( unsigned int ) GetLastError ( ) ) ;
return ( ioctl - > handle ! = INVALID_HANDLE_VALUE ) ;
2024-05-20 01:57:15 +02:00
}
static int
2024-11-25 21:23:28 +01:00
plat_cdrom_load ( void * local )
2024-05-20 01:57:15 +02:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
plat_cdrom_close ( local ) ;
2024-05-20 01:57:15 +02:00
2024-11-25 21:23:28 +01:00
ioctl - > handle = CreateFileW ( ( LPCWSTR ) ioctl - > path , GENERIC_READ | GENERIC_WRITE ,
FILE_SHARE_READ | FILE_SHARE_WRITE , NULL , OPEN_EXISTING , 0 , NULL ) ;
win_cdrom_ioctl_log ( " handle=%p, error=%x \n " , ioctl - > handle , ( unsigned int ) GetLastError ( ) ) ;
if ( ioctl - > handle ! = INVALID_HANDLE_VALUE ) {
2024-05-18 22:37:49 +02:00
long size ;
2024-11-25 21:23:28 +01:00
DeviceIoControl ( ioctl - > handle , IOCTL_STORAGE_LOAD_MEDIA , NULL , 0 , NULL , 0 , ( LPDWORD ) & size , NULL ) ;
2024-05-18 22:37:49 +02:00
return 1 ;
}
return 0 ;
}
2023-12-07 20:30:48 +01:00
2024-11-25 21:23:28 +01:00
static int
plat_cdrom_read_normal_toc ( win_cdrom_ioctl_t * ioctl , uint8_t * toc_buf )
{
long size = 0 ;
memset ( toc_buf , 0x00 , 65536 ) ;
plat_cdrom_open ( ioctl ) ;
int temp = DeviceIoControl ( ioctl - > handle , IOCTL_CDROM_READ_TOC , NULL , 0 , toc_buf , 65535 , ( LPDWORD ) & size , NULL ) ;
plat_cdrom_close ( ioctl ) ;
# ifdef ENABLE_WIN_CDROM_IOCTL_LOG
win_cdrom_ioctl_log ( " temp = %i \n " , temp ) ;
PCDROM_TOC toc = ( PCDROM_TOC ) toc_buf ;
const int tracks_num = ( ( ( toc - > Length [ 0 ] < < 8 ) | toc - > Length [ 1 ] ) - 2 ) / 8 ;
win_cdrom_ioctl_log ( " %i tracks \n " , tracks_num ) ;
for ( int i = 0 ; i < tracks_num ; i + + )
win_cdrom_ioctl_log ( " Track %03i: Point %02X \n " , i , ( int ) toc - > TrackData [ i ] . TrackNumber ) ;
# endif
return temp ;
}
2024-05-19 21:17:57 +02:00
static void
2024-11-25 21:23:28 +01:00
plat_cdrom_read_raw_toc ( win_cdrom_ioctl_t * ioctl )
2024-05-19 21:17:57 +02:00
{
2024-11-25 21:23:28 +01:00
long size = 0 ;
int status ;
PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL ;
memset ( ioctl - > cur_rti , 0x00 , 65536 ) ;
cur_full_toc = ( PCDROM_TOC_FULL_TOC_DATA ) calloc ( 1 , 65536 ) ;
if ( ioctl - > blocks_num ! = 0 ) {
memset ( ioctl - > cur_rti , 0x00 , ioctl - > blocks_num * 11 ) ;
ioctl - > blocks_num = 0 ;
}
ioctl - > cur_read_toc_ex . Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC ;
win_cdrom_ioctl_log ( " cur_read_toc_ex.Format = %i \n " , ioctl - > cur_read_toc_ex . Format ) ;
ioctl - > cur_read_toc_ex . Msf = 1 ;
ioctl - > cur_read_toc_ex . SessionTrack = 1 ;
2024-05-19 21:17:57 +02:00
2024-11-25 21:23:28 +01:00
plat_cdrom_open ( ioctl ) ;
status = DeviceIoControl ( ioctl - > handle , IOCTL_CDROM_READ_TOC_EX , & ioctl - > cur_read_toc_ex , 65535 ,
cur_full_toc , 65535 , ( LPDWORD ) & size , NULL ) ;
plat_cdrom_close ( ioctl ) ;
win_cdrom_ioctl_log ( " status = %i \n " , status ) ;
if ( status ! = 0 ) {
ioctl - > blocks_num = ( ( ( cur_full_toc - > Length [ 0 ] < < 8 ) | cur_full_toc - > Length [ 1 ] ) - 2 ) / 11 ;
memcpy ( ioctl - > cur_rti , cur_full_toc - > Descriptors , ioctl - > blocks_num * 11 ) ;
}
free ( cur_full_toc ) ;
# ifdef ENABLE_WIN_CDROM_IOCTL_LOG
win_cdrom_ioctl_log ( " %i blocks \n " , ioctl - > blocks_num ) ;
raw_track_info_t * rti = ( raw_track_info_t * ) ioctl - > cur_rti ;
for ( int i = 0 ; i < ioctl - > blocks_num ; i + + )
win_cdrom_ioctl_log ( " Block %03i: Session %03i, Point %02X \n " , i , ( int ) rti [ i ] . session , ( int ) rti [ i ] . point ) ;
# endif
}
void
plat_cdrom_get_raw_track_info ( void * local , int * num , raw_track_info_t * rti )
{
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
* num = ioctl - > blocks_num ;
memcpy ( rti , ioctl - > cur_rti , ioctl - > blocks_num * 11 ) ;
}
static void
plat_cdrom_read_toc ( win_cdrom_ioctl_t * ioctl )
{
if ( ! ioctl - > toc_valid ) {
ioctl - > toc_valid = 1 ;
( void ) plat_cdrom_read_normal_toc ( ioctl , ioctl - > cur_toc ) ;
plat_cdrom_read_raw_toc ( ioctl ) ;
2024-05-19 21:17:57 +02:00
}
}
2023-12-07 20:30:48 +01:00
int
2024-11-25 21:23:28 +01:00
plat_cdrom_is_track_audio ( void * local , uint32_t sector )
2023-12-07 20:30:48 +01:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
PCDROM_TOC toc = ( PCDROM_TOC ) ioctl - > cur_toc ;
int control = 0 ;
uint32_t cur_addr = 0 ;
uint32_t next_addr = 0 ;
plat_cdrom_read_toc ( ioctl ) ;
2024-05-19 21:17:57 +02:00
2024-11-25 21:23:28 +01:00
for ( int c = 0 ; toc - > TrackData [ c ] . TrackNumber ! = 0xaa ; c + + ) {
PTRACK_DATA cur_td = & toc - > TrackData [ c ] ;
PTRACK_DATA next_td = & toc - > TrackData [ c + 1 ] ;
cur_addr = MSFtoLBA ( cur_td - > Address [ 1 ] , cur_td - > Address [ 2 ] , cur_td - > Address [ 3 ] ) - 150 ;
next_addr = MSFtoLBA ( next_td - > Address [ 1 ] , next_td - > Address [ 2 ] , next_td - > Address [ 3 ] ) - 150 ;
2024-05-19 21:17:57 +02:00
win_cdrom_ioctl_log ( " F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X \n " ,
2024-11-25 21:23:28 +01:00
toc - > FirstTrack , toc - > LastTrack , cur_td - > TrackNumber , c ,
cur_td - > Control , track_addr , sector ) ;
if ( ( cur_td - > TrackNumber > = toc - > FirstTrack ) & & ( cur_td - > TrackNumber < = toc - > LastTrack ) & &
( sector > = cur_addr ) & & ( sector < next_addr ) ) {
control = cur_td - > Control ;
2024-05-19 21:17:57 +02:00
break ;
}
}
2024-05-18 19:42:00 +02:00
2024-05-19 21:17:57 +02:00
const int ret = ! ( control & 0x04 ) ;
win_cdrom_ioctl_log ( " plat_cdrom_is_track_audio(%08X): %i \n " , sector , ret ) ;
return ret ;
}
2024-05-18 19:42:00 +02:00
2024-05-20 01:57:15 +02:00
int
2024-11-25 21:23:28 +01:00
plat_cdrom_is_track_pre ( void * local , uint32_t sector )
2024-05-19 21:17:57 +02:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
PCDROM_TOC toc = ( PCDROM_TOC ) ioctl - > cur_toc ;
int control = 0 ;
uint32_t cur_addr = 0 ;
uint32_t next_addr = 0 ;
plat_cdrom_read_toc ( ioctl ) ;
for ( int c = 0 ; toc - > TrackData [ c ] . TrackNumber ! = 0xaa ; c + + ) {
PTRACK_DATA cur_td = & toc - > TrackData [ c ] ;
PTRACK_DATA next_td = & toc - > TrackData [ c + 1 ] ;
2024-05-19 21:17:57 +02:00
2024-11-25 21:23:28 +01:00
cur_addr = MSFtoLBA ( cur_td - > Address [ 1 ] , cur_td - > Address [ 2 ] , cur_td - > Address [ 3 ] ) - 150 ;
next_addr = MSFtoLBA ( next_td - > Address [ 1 ] , next_td - > Address [ 2 ] , next_td - > Address [ 3 ] ) - 150 ;
2024-05-19 21:17:57 +02:00
win_cdrom_ioctl_log ( " F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X \n " ,
2024-11-25 21:23:28 +01:00
toc - > FirstTrack , toc - > LastTrack , cur_td - > TrackNumber , c ,
cur_td - > Control , cur_addr , sector ) ;
if ( ( cur_td - > TrackNumber > = toc - > FirstTrack ) & & ( cur_td - > TrackNumber < = toc - > LastTrack ) & &
( sector > = cur_addr ) & & ( sector < next_addr ) ) {
control = cur_td - > Control ;
2024-05-20 01:57:15 +02:00
break ;
2024-11-25 21:23:28 +01:00
}
2024-05-20 01:57:15 +02:00
}
const int ret = ( control & 0x01 ) ;
win_cdrom_ioctl_log ( " plat_cdrom_is_track_audio(%08X): %i \n " , sector , ret ) ;
return ret ;
}
uint32_t
2024-11-25 21:23:28 +01:00
plat_cdrom_get_track_start ( void * local , uint32_t sector , uint8_t * attr , uint8_t * track )
2024-05-20 01:57:15 +02:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
PCDROM_TOC toc = ( PCDROM_TOC ) ioctl - > cur_toc ;
uint32_t cur_addr = 0 ;
uint32_t next_addr = 0 ;
plat_cdrom_read_toc ( ioctl ) ;
for ( int c = 0 ; toc - > TrackData [ c ] . TrackNumber ! = 0xaa ; c + + ) {
PTRACK_DATA cur_td = & toc - > TrackData [ c ] ;
PTRACK_DATA next_td = & toc - > TrackData [ c + 1 ] ;
2024-05-20 01:57:15 +02:00
2024-11-25 21:23:28 +01:00
cur_addr = MSFtoLBA ( cur_td - > Address [ 1 ] , cur_td - > Address [ 2 ] , cur_td - > Address [ 3 ] ) - 150 ;
next_addr = MSFtoLBA ( next_td - > Address [ 1 ] , next_td - > Address [ 2 ] , next_td - > Address [ 3 ] ) - 150 ;
2024-05-20 01:57:15 +02:00
win_cdrom_ioctl_log ( " F: %i, L: %i, C: %i (%i), c: %02X, a: %02X, A: %08X, S: %08X \n " ,
2024-11-25 21:23:28 +01:00
toc - > FirstTrack , toc - > LastTrack , cur_td - > TrackNumber , c ,
cur_td - > Control , cur_td - > Adr , cur_addr , sector ) ;
if ( ( cur_td - > TrackNumber > = toc - > FirstTrack ) & & ( cur_td - > TrackNumber < = toc - > LastTrack ) & &
( sector > = cur_addr ) & & ( sector < next_addr ) ) {
* track = cur_td - > TrackNumber ;
* attr = cur_td - > Control ;
* attr | = ( ( cur_td - > Adr < < 4 ) & 0xf0 ) ;
2023-12-07 20:30:48 +01:00
break ;
2024-05-19 21:17:57 +02:00
}
2023-12-07 20:30:48 +01:00
}
2024-05-19 21:17:57 +02:00
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_log ( " plat_cdrom_get_track_start(%08X): %i \n " , sector , cur_addr ) ;
2024-05-19 21:17:57 +02:00
2024-11-25 21:23:28 +01:00
return cur_addr ;
2023-12-07 20:30:48 +01:00
}
2024-05-19 21:17:57 +02:00
uint32_t
2024-11-25 21:23:28 +01:00
plat_cdrom_get_last_block ( void * local )
2023-12-07 20:30:48 +01:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
PCDROM_TOC toc = ( PCDROM_TOC ) ioctl - > cur_toc ;
uint32_t lb = 0 ;
uint32_t address = 0 ;
2024-05-18 19:42:00 +02:00
2024-11-25 21:23:28 +01:00
plat_cdrom_read_toc ( ioctl ) ;
for ( int c = 0 ; c < = toc - > LastTrack ; c + + ) {
PTRACK_DATA td = & toc - > TrackData [ c ] ;
address = MSFtoLBA ( td - > Address [ 1 ] , td - > Address [ 2 ] , td - > Address [ 3 ] ) - 150 ;
2024-05-18 19:42:00 +02:00
if ( address > lb )
lb = address ;
}
2024-11-25 21:23:28 +01:00
2024-05-19 21:17:57 +02:00
win_cdrom_ioctl_log ( " LBCapacity=%d \n " , lb ) ;
2024-11-25 21:23:28 +01:00
2024-05-18 19:42:00 +02:00
return lb ;
2023-12-07 20:30:48 +01:00
}
2024-05-19 21:17:57 +02:00
int
2024-11-25 21:23:28 +01:00
plat_cdrom_ext_medium_changed ( void * local )
2023-12-07 20:30:48 +01:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
PCDROM_TOC toc = ( PCDROM_TOC ) ioctl - > cur_toc ;
uint8_t new_toc_buf [ 65536 ] = { 0 } ;
PCDROM_TOC new_toc = ( PCDROM_TOC ) new_toc_buf ;
int ret = 0 ;
int temp = plat_cdrom_read_normal_toc ( ioctl , new_toc_buf ) ;
PTRACK_DATA cur_ltd = & toc - > TrackData [ toc - > LastTrack ] ;
2023-12-07 20:30:48 +01:00
2024-11-25 21:23:28 +01:00
if ( temp ! = 0 )
plat_cdrom_read_raw_toc ( ioctl ) ;
2023-12-07 20:30:48 +01:00
2024-11-25 21:23:28 +01:00
PTRACK_DATA new_ltd = & new_toc - > TrackData [ new_toc - > LastTrack ] ;
if ( temp = = 0 )
2024-05-19 21:17:57 +02:00
/* There has been some kind of error - not a medium change, but a not ready
condition . */
ret = - 1 ;
2024-11-25 21:23:28 +01:00
else if ( ! ioctl - > toc_valid | | ( memcmp ( ioctl - > path , ioctl - > old_path , sizeof ( ioctl - > path ) ) ! = 0 ) ) {
2024-05-19 21:17:57 +02:00
/* Changed to a different host drive - we already detect such medium changes. */
2024-11-25 21:23:28 +01:00
ioctl - > toc_valid = 1 ;
memcpy ( toc , new_toc , 65535 ) ;
if ( memcmp ( ioctl - > path , ioctl - > old_path , sizeof ( ioctl - > path ) ) ! = 0 )
memcpy ( ioctl - > old_path , ioctl - > path , sizeof ( ioctl - > path ) ) ;
} else if ( memcmp ( & ( new_ltd - > Address [ 1 ] ) , & ( cur_ltd - > Address [ 1 ] ) , 3 ) )
2024-05-19 21:17:57 +02:00
/* The TOC has changed. */
ret = 1 ;
win_cdrom_ioctl_log ( " plat_cdrom_ext_medium_changed(): %i \n " , ret ) ;
return ret ;
}
void
2024-11-25 21:23:28 +01:00
plat_cdrom_get_audio_tracks ( void * local , int * st_track , int * end , TMSF * lead_out )
2024-05-19 21:17:57 +02:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
PCDROM_TOC toc = ( PCDROM_TOC ) ioctl - > cur_toc ;
plat_cdrom_read_toc ( ioctl ) ;
PTRACK_DATA ltd = & toc - > TrackData [ toc - > LastTrack ] ;
2024-05-19 21:17:57 +02:00
2024-05-18 19:42:00 +02:00
* st_track = 1 ;
2024-11-25 21:23:28 +01:00
* end = toc - > LastTrack ;
lead_out - > min = ltd - > Address [ 1 ] ;
lead_out - > sec = ltd - > Address [ 2 ] ;
lead_out - > fr = ltd - > Address [ 3 ] ;
2024-05-19 21:17:57 +02:00
win_cdrom_ioctl_log ( " plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i \n " ,
* st_track , * end , lead_out - > min , lead_out - > sec , lead_out - > fr ) ;
2023-12-07 20:30:48 +01:00
}
/* This replaces both Info and EndInfo, they are specified by a variable. */
int
2024-11-25 21:23:28 +01:00
plat_cdrom_get_audio_track_info ( void * local , UNUSED ( int end ) , int track , int * track_num , TMSF * start , uint8_t * attr )
2023-12-07 20:30:48 +01:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
PCDROM_TOC toc = ( PCDROM_TOC ) ioctl - > cur_toc ;
2023-12-07 20:30:48 +01:00
2024-11-25 21:23:28 +01:00
plat_cdrom_read_toc ( ioctl ) ;
if ( ( track < 1 ) | | ( track = = 0xaa ) | | ( track > ( toc - > LastTrack + 1 ) ) ) {
2024-05-19 21:17:57 +02:00
win_cdrom_ioctl_log ( " plat_cdrom_get_audio_track_info(%02i) \n " , track ) ;
2023-12-07 20:30:48 +01:00
return 0 ;
2024-05-19 21:17:57 +02:00
}
2024-11-25 21:23:28 +01:00
PTRACK_DATA td = & toc - > TrackData [ track - 1 ] ;
start - > min = td - > Address [ 1 ] ;
start - > sec = td - > Address [ 2 ] ;
start - > fr = td - > Address [ 3 ] ;
2023-12-07 20:30:48 +01:00
2024-11-25 21:23:28 +01:00
* track_num = td - > TrackNumber ;
* attr = td - > Control ;
* attr | = ( ( td - > Adr < < 4 ) & 0xf0 ) ;
2023-12-07 20:30:48 +01:00
2024-05-19 21:17:57 +02:00
win_cdrom_ioctl_log ( " plat_cdrom_get_audio_track_info(%02i): %02i:%02i:%02i, %02i, %02X \n " ,
track , start - > min , start - > sec , start - > fr , * track_num , * attr ) ;
2023-12-07 20:30:48 +01:00
return 1 ;
}
2024-05-18 19:42:00 +02:00
/* TODO: See if track start is adjusted by 150 or not. */
2023-12-07 20:30:48 +01:00
int
2024-11-25 21:23:28 +01:00
plat_cdrom_get_audio_sub ( void * local , UNUSED ( uint32_t sector ) , uint8_t * attr , uint8_t * track , uint8_t * index ,
TMSF * rel_pos , TMSF * abs_pos )
2023-12-07 20:30:48 +01:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
2024-05-19 21:17:57 +02:00
CDROM_SUB_Q_DATA_FORMAT insub ;
2024-11-25 21:23:28 +01:00
SUB_Q_CHANNEL_DATA sub ;
long size = 0 ;
2023-12-07 20:30:48 +01:00
2024-05-18 19:42:00 +02:00
insub . Format = IOCTL_CDROM_CURRENT_POSITION ;
2023-12-07 20:30:48 +01:00
2024-11-25 21:23:28 +01:00
plat_cdrom_open ( ioctl ) ;
DeviceIoControl ( ioctl - > handle , IOCTL_CDROM_READ_Q_CHANNEL , & insub , sizeof ( insub ) , & sub , sizeof ( sub ) ,
( LPDWORD ) & size , NULL ) ;
plat_cdrom_close ( ioctl ) ;
2023-12-07 20:30:48 +01:00
2024-05-18 19:42:00 +02:00
if ( sub . CurrentPosition . TrackNumber < 1 )
return 0 ;
2023-12-07 20:30:48 +01:00
2024-05-18 19:42:00 +02:00
* track = sub . CurrentPosition . TrackNumber ;
* attr = sub . CurrentPosition . Control ;
2024-05-20 01:57:15 +02:00
* attr | = ( ( sub . CurrentPosition . ADR < < 4 ) & 0xf0 ) ;
2024-05-18 19:42:00 +02:00
* index = sub . CurrentPosition . IndexNumber ;
2023-12-07 20:30:48 +01:00
2024-05-19 21:17:57 +02:00
rel_pos - > min = sub . CurrentPosition . TrackRelativeAddress [ 1 ] ;
rel_pos - > sec = sub . CurrentPosition . TrackRelativeAddress [ 2 ] ;
rel_pos - > fr = sub . CurrentPosition . TrackRelativeAddress [ 3 ] ;
abs_pos - > min = sub . CurrentPosition . AbsoluteAddress [ 1 ] ;
abs_pos - > sec = sub . CurrentPosition . AbsoluteAddress [ 2 ] ;
abs_pos - > fr = sub . CurrentPosition . AbsoluteAddress [ 3 ] ;
win_cdrom_ioctl_log ( " plat_cdrom_get_audio_sub(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i \n " ,
2024-11-25 21:23:28 +01:00
* track , * attr , * index , rel_pos - > min , rel_pos - > sec , rel_pos - > fr , abs_pos - > min , abs_pos - > sec ,
abs_pos - > fr ) ;
2023-12-07 20:30:48 +01:00
return 1 ;
}
int
2024-11-25 21:23:28 +01:00
plat_cdrom_get_sector_size ( void * local , UNUSED ( uint32_t sector ) )
2023-12-07 20:30:48 +01:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
long size ;
DISK_GEOMETRY dgCDROM ;
2024-05-18 22:37:49 +02:00
2024-11-25 21:23:28 +01:00
plat_cdrom_open ( ioctl ) ;
DeviceIoControl ( ioctl - > handle , IOCTL_CDROM_GET_DRIVE_GEOMETRY , NULL , 0 , & dgCDROM , sizeof ( dgCDROM ) ,
( LPDWORD ) & size , NULL ) ;
plat_cdrom_close ( ioctl ) ;
2024-07-20 19:55:47 +02:00
win_cdrom_ioctl_log ( " BytesPerSector=%d \n " , dgCDROM . BytesPerSector ) ;
return dgCDROM . BytesPerSector ;
2023-12-07 20:30:48 +01:00
}
2024-05-18 19:42:00 +02:00
int
2024-11-25 21:23:28 +01:00
plat_cdrom_read_sector ( void * local , uint8_t * buffer , int raw , uint32_t sector )
2023-12-07 20:30:48 +01:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
int status ;
long size = 0 ;
int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE ;
2024-05-18 19:42:00 +02:00
2024-11-25 21:23:28 +01:00
plat_cdrom_open ( ioctl ) ;
2024-05-18 19:42:00 +02:00
2024-05-20 01:57:15 +02:00
if ( raw ) {
2024-05-19 21:17:57 +02:00
/* Raw */
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_log ( " Raw \n " ) ;
2024-07-20 19:55:47 +02:00
RAW_READ_INFO in ;
in . DiskOffset . LowPart = sector * COOKED_SECTOR_SIZE ;
in . DiskOffset . HighPart = 0 ;
in . SectorCount = 1 ;
in . TrackMode = CDDA ;
2024-11-25 21:23:28 +01:00
status = DeviceIoControl ( ioctl - > handle , IOCTL_CDROM_RAW_READ , & in , sizeof ( in ) ,
buffer , buflen , ( LPDWORD ) & size , NULL ) ;
2024-05-20 01:57:15 +02:00
} else {
/* Cooked */
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_log ( " Cooked \n " ) ;
2024-05-20 01:57:15 +02:00
int success = 0 ;
2024-11-25 21:23:28 +01:00
DWORD newPos = SetFilePointer ( ioctl - > handle , sector * COOKED_SECTOR_SIZE , 0 , FILE_BEGIN ) ;
2024-05-20 01:57:15 +02:00
if ( newPos ! = 0xFFFFFFFF )
2024-11-25 21:23:28 +01:00
success = ReadFile ( ioctl - > handle , buffer , buflen , ( LPDWORD ) & size , NULL ) ;
2024-05-20 01:57:15 +02:00
status = ( success ! = 0 ) ;
2024-05-19 21:17:57 +02:00
}
2024-11-25 21:23:28 +01:00
plat_cdrom_close ( ioctl ) ;
2024-05-20 01:57:15 +02:00
win_cdrom_ioctl_log ( " ReadSector status=%d, sector=%d, size=% " PRId64 " . \n " , status , sector , ( long long ) size ) ;
2024-05-19 21:17:57 +02:00
2024-10-27 13:17:55 -03:00
return ( status > 0 ) ? ( size = = buflen ) : - 1 ;
2023-12-07 20:30:48 +01:00
}
2024-05-18 22:37:49 +02:00
void
2024-11-25 21:23:28 +01:00
plat_cdrom_eject ( void * local )
2024-05-18 22:37:49 +02:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
long size ;
2024-05-19 21:17:57 +02:00
2024-11-25 21:23:28 +01:00
plat_cdrom_open ( ioctl ) ;
DeviceIoControl ( ioctl - > handle , IOCTL_STORAGE_EJECT_MEDIA , NULL , 0 , NULL , 0 , ( LPDWORD ) & size , NULL ) ;
plat_cdrom_close ( ioctl ) ;
2024-05-18 22:37:49 +02:00
}
2023-12-07 20:30:48 +01:00
void
2024-11-25 21:23:28 +01:00
plat_cdrom_close ( void * local )
2023-12-07 20:30:48 +01:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
if ( ioctl - > handle ! = NULL ) {
CloseHandle ( ioctl - > handle ) ;
ioctl - > handle = NULL ;
2024-05-18 19:42:00 +02:00
}
2023-12-07 20:30:48 +01:00
}
2024-05-18 22:37:49 +02:00
int
2024-11-25 21:23:28 +01:00
plat_cdrom_set_drive ( void * local , const char * drv )
2023-12-07 20:30:48 +01:00
{
2024-11-25 21:23:28 +01:00
win_cdrom_ioctl_t * ioctl = ( win_cdrom_ioctl_t * ) local ;
plat_cdrom_close ( ioctl ) ;
2024-05-18 19:42:00 +02:00
2024-11-25 21:23:28 +01:00
memcpy ( ioctl - > old_path , ioctl - > path , sizeof ( ioctl - > path ) ) ;
memset ( ioctl - > path , 0x00 , sizeof ( ioctl - > path ) ) ;
2024-05-19 21:17:57 +02:00
2024-11-25 21:23:28 +01:00
wsprintf ( ioctl - > path , L " %S " , drv ) ;
win_cdrom_ioctl_log ( " Path is %S \n " , ioctl - > path ) ;
2024-05-19 21:17:57 +02:00
2024-11-25 21:23:28 +01:00
ioctl - > toc_valid = 0 ;
plat_cdrom_load ( ioctl ) ;
2023-12-07 20:30:48 +01:00
2024-05-18 22:37:49 +02:00
return 1 ;
2023-12-07 20:30:48 +01:00
}
2024-11-25 21:23:28 +01:00
int
plat_cdrom_get_local_size ( void )
{
return sizeof ( win_cdrom_ioctl_t ) ;
}