VOGONS


ioctl vs. noioctl ways in Vista

Topic actions

Reply 20 of 48, by gidierre

User metadata
Rank Member
Rank
Member

Alright lads, this is it, Logtime again!

You've got it coming.
[ohnonothimagain]

actually without Qbix's immediate and active assistance (thank you so much) chances were no log was going to come, as at first after installing the pdcurses libraries using them turned out to be quite problematic to me, since msys would refuse to locate them...(this is Windows)

/*

I don't know if this might somewhen matter to someone else, but this might be helpful info if only for other inept users (like me), after all if Forums are aimed to diffusing competence, hence are postulating incompetence, and you can bet I'm a real expert at inexpertise, so why shouldn't I add here that
after Qbix helped me out,
I still kept on investigating a little more on MinGW/Msys not finding curses.h etc. fumbling for some fix and I guess I found a way after all :

finally used a different pdcurses-2.6.0-2003.07.21-1.exe setup for them, installed over my c:\mingw folder
(as opposed to install into "c:\program files\something" and then trying to fiddle with some export path= expression in msys, and other unlucky previous shots at it)
and finally I could create a cute debug enabled dosbox.exe too ! 😀

*/

OK, so these are the 2 new logs.

I started comparing them, not via a real binary comparison, because it's meaningless imo (I can't trust the timings of 2 separate sessions to be close enough)
but through just a sequence of vertical juxtapositions of the logs' windows (see if it's some use the screens I took...)

By my first glimpse, and by what I can make of it, hoping to avoid uttering an excessive amount of foolishnesses, I'd say the logging of
MSCDEX: IOCTL INPUT Subfunction 0B and get audio track info
gives no sign of a different pattern (compare1.jpg)

The subsequent mscdex calls are identical except on noioctl (music on) side
there are these calls

55075306: MISC:MSCDEX: INT 2F 1510 BX= 0000 CX=0003
55075306: MISC:MSCDEX: Driver Function 03
55075306: MISC:MSCDEX: IOCTL INPUT Subfunction 06
55075306: MISC:MSCDEX: Status : 0300
55075324: MISC:MSCDEX: INT 2F 1510 BX= 0000 CX=0003
55075324: MISC:MSCDEX: Driver Function 03
55075324: MISC:MSCDEX: IOCTL INPUT Subfunction 0C
55075324: MISC:MSCDEX: Status : 0300

unmatched by any in ioctl (compare2.jpg)

They're for
case 0x06 : /* Get Device status */
and
case 0x0C : /* Get Audio Sub Channel data */

Doubtful whether they carry any real significance though.

Probably in 1 day or 2 I'll try to take one more couple of log shots to see what happens.

Attachments

  • Filename
    ioctl log.txt
    File size
    21.18 KiB
    Downloads
    336 downloads
    File license
    Fair use/fair dealing exception
  • Filename
    noioctl log.txt
    File size
    24.25 KiB
    Downloads
    347 downloads
    File license
    Fair use/fair dealing exception
  • Filename
    comparison.zip
    File size
    574.94 KiB
    Downloads
    406 downloads
    File license
    Fair use/fair dealing exception

Reply 21 of 48, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

but through just a sequence of vertical juxtapositions of the logs' windows (see if it's some use the screens I took...)

Use examdiff of diffmerge to automate this process.
Also try getting rid of some unnecessary log output that makes the log file
less readable, like disable the Raising IRQ message (sblaster.cpp).

The logs are indeed equal with respect to the relevant mscdex operations.
It might very well be that everything works fine, just the "play audio" call
is ignored.
Anyway, try adding some more detailed logging at the 0x84/0x85 subfunctions
(maybe for some reason the wrong start address for audio tracks is used).

Reply 22 of 48, by gidierre

User metadata
Rank Member
Rank
Member
wd wrote:

like disable the Raising IRQ message (sblaster.cpp).

done

wd wrote:
The logs are indeed equal with respect to the relevant mscdex operations. It might very well be that everything works fine, just […]
Show full quote

The logs are indeed equal with respect to the relevant mscdex operations.
It might very well be that everything works fine, just the "play audio" call
is ignored.
Anyway, try adding some more detailed logging at the 0x84/0x85 subfunctions
(maybe for some reason the wrong start address for audio tracks is used).

I tried adding one LOG_MSG here @ subfunction 0x84

		case 0x84	: {	/* Play Audio Sectors */
Bit32u start = mem_readd(curReqheaderPtr+0x0E);
Bit32u len = mem_readd(curReqheaderPtr+0x12);
if (mem_readb(curReqheaderPtr+0x0D)==0x00) // HSG
mscdex->PlayAudioSector(subUnit,start,len);
else // RED BOOK
mscdex->PlayAudioMSF(subUnit,start,len);
LOG_MSG("start: %d, len: %d, subUnit: %d", start,len,subUnit);
break;
};

I'm not sure whether this is just what you had in mind though

as for subf. 0x85 I've been looking into the implementation of
bool StopAudio()
i.e.

bool CMscdex::StopAudio(Bit8u subUnit);
{
if (subUnit>=numDrives) return false;
if (dinfo[subUnit].audioPlay) dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(false);
else dinfo[subUnit].lastResult = cdrom[subUnit]->StopAudio();

if (dinfo[subUnit].lastResult) {
if (dinfo[subUnit].audioPlay) {
TMSF pos;
GetCurrentPos(subUnit,pos);
dinfo[subUnit].audioStart = pos.min*60*75+pos.sec*75+pos.fr - 150;
dinfo[subUnit].audioPaused = true;
} else {
dinfo[subUnit].audioPaused = false;
dinfo[subUnit].audioStart = 0;
dinfo[subUnit].audioEnd = 0;
};
dinfo[subUnit].audioPlay = false;
};
return dinfo[subUnit].lastResult;
};

but am unsure as to what to consider worthwhile logging.
Maybe dinfo[subUnit].audioPlay ?
or dinfo[subUnit].lastResult, which can be the return value of StopAudio() and of GetCDInfo() and other functions as well ?
But do they matter anyway ?

Here are the 2 new logs, sorry I didn't try the diffmerge util yet.
In these logs, still nothing there as far as I can see that throws some light.

Attachments

  • Filename
    ioctl log 3.txt
    File size
    14.29 KiB
    Downloads
    371 downloads
    File license
    Fair use/fair dealing exception
  • Filename
    noioctl log 3.txt
    File size
    14.5 KiB
    Downloads
    365 downloads
    File license
    Fair use/fair dealing exception

Reply 23 of 48, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Are the logs (both) fully reproducable? As the noioctl-one has two additional
audio channel control calls somewhere at the end.

Try checking/logging what CMscdex::PlayAudioSector and CMscdex::StopAudio
actually do, especially if dinfo[subUnit].audioPaused is consistent (so both times
the PlayAudioSector call does start the playback).

And maybe add full logging to case 0x0C : Get Audio Sub Channel data
and case 0x06 : Get Device status of the ioctl input functions.

Reply 24 of 48, by gidierre

User metadata
Rank Member
Rank
Member

I will surely add the dinfo[subUnit].audioPaused check as soon as I am able.

There's a point though still lingering here that I'd really love to discuss in advance, for I somehow fear I'm going in circles around the ioctl obsoleteness in Vista, along the lines of the IOCTL_CDROM_READ_Q_CHANNEL issue shown here:
http://msdn2.microsoft.com/en-us/library/ms803640.aspx
("Obsolete, beginning with the Windows Vista. Do not use this IOCTL to develop drivers in Windows Vista.")

At the end of both logs there's the sequence

74507455: MISC:MSCDEX: INT 2F 1510 BX= 0000 CX=0003
74507455: MISC:MSCDEX: Driver Function 03
74507455: MISC:MSCDEX: IOCTL INPUT Subfunction 06
74507455: MISC:MSCDEX: Status : 0300
74507473: MISC:MSCDEX: INT 2F 1510 BX= 0000 CX=0003
74507473: MISC:MSCDEX: Driver Function 03
74507473: MISC:MSCDEX: IOCTL INPUT Subfunction 0C
74507473: MISC:MSCDEX: Status : 0300

It makes sense that the status amounts to track playing (or thinking it is in ioctl case) because here's when the music is/ought to be playing and I pack it in closing dosbox at once without exiting the game to spare time.

But how do I know it is (or should be) playing ?
In general, because I know what the game does at this point and in fact noioctl behaves exactly as expected, but from the debugging point of view

I think I do because of the Status variable outcome
(please be patient and forgive my being so slow pedantic and what have you) :

in dos_mscdex.cpp I can start from

static Bit16u MSCDEX_IOCTL_Input() {
...
switch (ioctl_fct) {
...
case 0x06 : /* Get Device status */
mem_writed(buffer+1,mscdex->GetDeviceStatus(drive_unit));
break;

via

// Request Status
#define REQUEST_STATUS_DONE 0x0100
#define REQUEST_STATUS_ERROR 0x8000

then

Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit);

then

static Bitu MSCDEX_Interrupt_Handler(void) {
...
// huge switch
...
// Set Statusword
mem_writew(curReqheaderPtr+3,mscdex->GetStatusWord(subUnit,errcode));
MSCDEX_LOG("MSCDEX: Status : %04X",mem_readw(curReqheaderPtr+3));
return CBRET_NONE;
}

cool, this is where the mscdex : status message in the log comes from,
so go ahead to

Bit16u CMscdex::GetStatusWord(Bit8u subUnit,Bit16u status)
{
if (subUnit>=numDrives) return REQUEST_STATUS_ERROR | 0x02; // error : Drive not ready

if (dinfo[subUnit].lastResult) status |= REQUEST_STATUS_DONE; // ok
else status |= REQUEST_STATUS_ERROR;

if (dinfo[subUnit].audioPlay) {
// Check if audio is still playing....
TMSF start,end;
bool playing,pause;
if (GetAudioStatus(subUnit,playing,pause,start,end)) {
dinfo[subUnit].audioPlay = playing;
} else
dinfo[subUnit].audioPlay = false;

status |= (dinfo[subUnit].audioPlay<<9);
}
dinfo[subUnit].lastResult = true;
return status;
};

I conclude that if status == 0x0300, bit 8 and 9 set, right ?
this means that in
status |= (dinfo[subUnit].audioPlay<<9);

the line :
dinfo[subUnit].audioPlay = playing;

takes me to understand that bool playing == TRUE; right again ?

now this bool playing is just coming from GetAudioStatus(subUnit,playing,pause,start,end)

so, forward to

bool CMscdex::GetAudioStatus(Bit8u subUnit, bool& playing, bool& pause, TMSF& start, TMSF& end)
{
if (subUnit>=numDrives) return false;
dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioStatus(playing,pause);
if (dinfo[subUnit].lastResult) {
// Start
Bit32u addr = dinfo[subUnit].audioStart + 150;
start.fr = (Bit8u)(addr%75); addr/=75;
start.sec = (Bit8u)(addr%60);
start.min = (Bit8u)(addr/60);
// End
addr = dinfo[subUnit].audioEnd + 150;
end.fr = (Bit8u)(addr%75); addr/=75;
end.sec = (Bit8u)(addr%60);
end.min = (Bit8u)(addr/60);
} else {
playing = false;
pause = false;
memset(&start,0,sizeof(start));
memset(&end,0,sizeof(end));
};

return dinfo[subUnit].lastResult;
};

but finally here this line

dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioStatus(playing,pause);

does nothing else to me but point to 1 of 2 chances :

1.
case noioctl :
this is simpler here imho and above all more reliable in Vista.

jump to
cdrom.cpp

bool CDROM_Interface_SDL::GetAudioStatus (bool& playing, bool& pause)
{
if (CD_INDRIVE(SDL_CDStatus(cd))) {
playing = (cd->status==CD_PLAYING);
pause = (cd->status==CD_PAUSED);
}
return CD_INDRIVE(SDL_CDStatus(cd));
};

here where does playing comes from ?
Apparently afaik from a SDL_CD structure

typedef struct{
int id;
CDstatus status;
int numtracks;
int cur_track;
int cur_frame;
SDL_CDtrack track[SDL_MAX_TRACKS+1];
} SDL_CD;

from its SDL_CDStatus data

/* Given a status, returns true if there's a disk in the drive */
#define CD_INDRIVE(status) ((int)status > 0)

typedef enum {
CD_TRAYEMPTY,
CD_STOPPED,
CD_PLAYING,
CD_PAUSED,
CD_ERROR = -1
} CDstatus;

hence I should conclude that here, if playing == TRUE, it's really true

2.
case ioctl :

jump to
cdrom_ioctl_win32.cpp

bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause)
{
// Open();

CDROM_SUB_Q_DATA_FORMAT insub;
SUB_Q_CHANNEL_DATA sub;
DWORD byteCount;

insub.Format = IOCTL_CDROM_CURRENT_POSITION;

BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub),
&sub, sizeof(sub), &byteCount,NULL);
// Close();
if (!bStat) return false;

playing = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS);
pause = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_PAUSED);

return true;
};

where the lines

SUB_Q_CHANNEL_DATA sub;
BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub),&byteCount, NULL);

and

playing = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS);

point to a bool playing value which is unreliable insofar as based on the obsolete IOCTL_CDROM_READ_Q_CHANNEL issue already shown above :
http://msdn2.microsoft.com/en-us/library/ms803640.aspx

Bottom line : if I didn't go astray, if the IOCTL business is abandoned, what to do about it ?

P.S.
sincerely sorry for the post lenght, hope you understand I felt I had no choice but writing it so or forgetting about it 🙁

Reply 25 of 48, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

These obsolete-entries are exactly the crucial point, because there is no
information if they are still working or not. It looks like many of them still
work just fine (but might not in later vista/+ releases) as they behave
identical as under xp.
Maybe you could compare the state/return values of
CDROM_Interface_Ioctl::GetAudioStatus under xp and vista (so using the
ioctl interface both times).

My suspect is that just the play back audio function does not start off,
yet does not return failure either.

if the IOCTL business is abandoned, what to do about it ?

Write hatemails to MS or so. The problem is mixing direct sector access
(ioctl needed) with audio capabilities (mm stuff, like sdl does it).

Reply 26 of 48, by gidierre

User metadata
Rank Member
Rank
Member

wd :

I'm using another pc with win xp home sp2 at this time so hopefully soon I'm gonna recompile and be able to test\compare
BOOL bStat
values in CDROM_Interface_Ioctl::GetAudioStatus()
both under xp & vista (on 2 different machines anyway) and also adding some more log messages as you suggested.

Began to use diffmerge too 😎

Btw, curiosity killed the cat, but what's with these strange comments about forcing SDL_CDOpen() and a SDL bug in

bool CDROM_Interface_SDL::PlayAudioSector (unsigned long start,unsigned long len) 
{
// Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?)
SDL_CDClose(cd);
cd = SDL_CDOpen(driveID);
bool success = (SDL_CDPlay(cd,start+150,len)==0);
return success;
};

and

bool CDROM_Interface_SDL::StopAudio	(void) 
{
// Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?)
SDL_CDClose(cd);
cd = SDL_CDOpen(driveID);
bool success = (SDL_CDStop(cd)==0);
return success;
};

these comments accordingly are not there in CDROM_Interface_Ioctl::PlayAudioSector() nor in CDROM_Interface_Ioctl::StopAudio()

Reply 27 of 48, by gidierre

User metadata
Rank Member
Rank
Member

OK I thought I might as well start posting the fresh outcome with WindowsXP 😎

Splitting the report in two will hopefully make it easier to handle, for any reader as well as for your poor little worn out correspondent 😵 , not to speak I won't be messing with the vista pc until tomorrow 😜

I've been adding quite a few more log messages, hope wd that complies with your idea of full logging attitude (triple 😅 ).

To understand the changes maybe it's better if I detail the log lines I added into
cdrom_ioctl_win32.cpp
and
dos_mscdex.cpp

as per wd's requests when he wrote :

Maybe you could compare the state/return values of CDROM_Interface_Ioctl::GetAudioStatus under xp and vista (so using the ioctl […]
Show full quote

Maybe you could compare the state/return values of CDROM_Interface_Ioctl::GetAudioStatus under xp and vista (so using the ioctl interface both times).
....
Try checking/logging what CMscdex::PlayAudioSector and CMscdex::StopAudio
actually do, especially if dinfo[subUnit].audioPaused is consistent (so both times the PlayAudioSector call does start the playback).
And maybe add full logging to case 0x0C : Get Audio Sub Channel data
and case 0x06 : Get Device status of the ioctl input functions.

So here's the new recompiled code, you just lookup the new log lines :

in cdrom_ioctl_win32.cpp

bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause)
{
// Open();

CDROM_SUB_Q_DATA_FORMAT insub;
SUB_Q_CHANNEL_DATA sub;
DWORD byteCount;

insub.Format = IOCTL_CDROM_CURRENT_POSITION;

BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), &byteCount,NULL);

LOG_MSG("\nIn CDROM_Interface_Ioctl::GetAudioStatus\nValue of bStat= %d\n", bStat);

// Close();
if (!bStat) return false;

playing = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS);
pause = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_PAUSED);

LOG_MSG("\nIn CDROM_Interface_Ioctl::GetAudioStatus\nValue of playing= %d\n", playing);
LOG_MSG("\nIn CDROM_Interface_Ioctl::GetAudioStatus\nValue of pause= %d\n", pause);

return true;
};

in dos_mscdex.cpp

Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit)
{
if (subUnit>=numDrives) return false;
bool media,changed,trayOpen;

dinfo[subUnit].lastResult = GetMediaStatus(subUnit,media,changed,trayOpen);
Bit32u status = (trayOpen << 0) | // Drive is open ?
(dinfo[subUnit].locked << 1) | // Drive is locked ?
(1<<2) | // raw + cooked sectors
(1<<4) | // Can read sudio
(1<<9) | // Red book & HSG
((!media) << 11); // Drive is empty ?

LOG_MSG("\nIn CMscdex::GetDeviceStatus\nValue of status= %#x\n", status);

return status;
};

---

bool CMscdex::PlayAudioSector(Bit8u subUnit, Bit32u sector, Bit32u length)
{
if (subUnit>=numDrives) return false;
// If value from last stop is used, this is meant as a resume
// better start using resume command
if (dinfo[subUnit].audioPaused && (sector==dinfo[subUnit].audioStart)) {
dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(true);
} else
dinfo[subUnit].lastResult = cdrom[subUnit]->PlayAudioSector(sector,length);

LOG_MSG("\nIn CMscdex::PlayAudioSector\nValue of initial dinfo[subUnit].audioPaused= %d\n", dinfo[subUnit].audioPaused);

if (dinfo[subUnit].lastResult) {
dinfo[subUnit].audioPlay = true;
dinfo[subUnit].audioPaused = false;
dinfo[subUnit].audioStart = sector;
dinfo[subUnit].audioEnd = length;
};

LOG_MSG("\nIn CMscdex::PlayAudioSector\nValue of final dinfo[subUnit].audioPaused= %d\n", dinfo[subUnit].audioPaused);
LOG_MSG("\nIn CMscdex::PlayAudioSector\nValue of final dinfo[subUnit].audioPlay= %d\n", dinfo[subUnit].audioPlay);
LOG_MSG("\nIn CMscdex::PlayAudioSector\nValue of dinfo[subUnit].lastResult= %d\n", dinfo[subUnit].lastResult);

return dinfo[subUnit].lastResult;
};

---------------

bool CMscdex::StopAudio(Bit8u subUnit)
{
if (subUnit>=numDrives) return false;
if (dinfo[subUnit].audioPlay) dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(false);
else dinfo[subUnit].lastResult = cdrom[subUnit]->StopAudio();

LOG_MSG("\nIn CMscdex::StopAudio\nValue of initial dinfo[subUnit].audioPlay= %d\n", dinfo[subUnit].audioPlay);

if (dinfo[subUnit].lastResult) {
if (dinfo[subUnit].audioPlay) {
TMSF pos;
GetCurrentPos(subUnit,pos);
dinfo[subUnit].audioStart = pos.min*60*75+pos.sec*75+pos.fr - 150;
dinfo[subUnit].audioPaused = true;
} else {
dinfo[subUnit].audioPaused = false;
dinfo[subUnit].audioStart = 0;
dinfo[subUnit].audioEnd = 0;
};
dinfo[subUnit].audioPlay = false;
};

LOG_MSG("\nIn CMscdex::StopAudio\nValue of final dinfo[subUnit].audioPlay= %d\n", dinfo[subUnit].audioPlay);
LOG_MSG("\nIn CMscdex::StopAudio\nValue of dinfo[subUnit].lastResult= %d\n", dinfo[subUnit].lastResult);

return dinfo[subUnit].lastResult;
};

----------

static Bit16u MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) {
Bitu ioctl_fct = mem_readb(buffer);
MSCDEX_LOG("MSCDEX: IOCTL INPUT Subfunction %02X",ioctl_fct);
switch (ioctl_fct) {
...
case 0x0C :{/* Get Audio Sub Channel data */
Bit8u attr,track,index;
TMSF abs,rel;
mscdex->GetSubChannelData(drive_unit,attr,track,index,rel,abs);
LOG_MSG("get Audio Sub Channel data, attr %x, track %d, index %d, rel %d, abs %d",attr,track,index,rel,abs);
mem_writeb(buffer+1,attr);
mem_writeb(buffer+2,track);
mem_writeb(buffer+3,index);
mem_writeb(buffer+4,rel.min);
mem_writeb(buffer+5,rel.sec);
mem_writeb(buffer+6,rel.fr);
mem_writeb(buffer+7,0x00);
mem_writeb(buffer+8,abs.min);
mem_writeb(buffer+9,abs.sec);
mem_writeb(buffer+10,abs.fr);
break;
};

Any comment is more than welcome.

Attaching :

ioctl xp log & a screenshot

Tomorrow's assignement : use other pc with vista to add ioctl vista log, noioctl vista log and a diffmerge try with xp vs. vista output.

What's new so far (ugh!)

Well this log may well serve as a model of things working.

I noticed that CMscdex::GetDeviceStatus()
always gives me a value of
status=214h that is 0000 0010 0001 0100b
to interpret by means of

	Bit32u status = (trayOpen << 0)					|	// Drive is open ?
(dinfo[subUnit].locked << 1) | // Drive is locked ?
(1<<2) | // raw + cooked sectors
(1<<4) | // Can read sudio
(1<<9) | // Red book & HSG
((!media) << 11); // Drive is empty ?

which means, in other words, everything is fine imho.

CDROM_Interface_Ioctl::GetAudioStatus e.g. shows that BOOL bStat to always be == 1, which is proper.

It'll sure be nice to compare with ioctl in Vista 😀

Attachments

  • Filename
    attachment.zip
    File size
    153.76 KiB
    Downloads
    332 downloads
    File license
    Fair use/fair dealing exception

Reply 28 of 48, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

these comments accordingly are not there in CDROM_Interface_Ioctl::PlayAudioSector() nor in CDROM_Interface_Ioctl::StopAudio()

Guess the audio-play (or cd in drive) status is updated only for open calls, so this is needed.

Reply 29 of 48, by gidierre

User metadata
Rank Member
Rank
Member

Part II - RETURN OF THE JEDI-ERRE

Hey, I'm baaaack !!

[who's gonna kill him ?]

and bringing to you the (hopefully) last and final logs :
brand new ioctl vista log and noioctl vista log to match ioctl xp log of yesterday.

What surfaces ?

Two considerations so far :
I noticed that status (consistently == 214h in ioctl xp && noioctl vista) in ioctl vista starts as well being

241h == 0000 0010 0001 0100b

then abruptly @ line #420 in diffmerge it becomes (and will also stay @ line #450)

A15h == 0000 1010 0001 0101b

it doesn't take much research if you keep in mind CMscdex::GetDeviceStatus() to see the bites 0 and 11 differ, which means failure :
(trayOpen) == (!media) == TRUE;

It seems strange, but that is so.

One step back : I marked the moment the cd music starts or fails (I took note how the debugging window was going during the game, of course) :
well, I noticed the moment the music fails for the first time, is not there @ line #420 where ioctl vista status goes astray, but happened before (@ line #284) and that's a point where the current available variable values e.g. start: 87283, len: 14745, subUnit: 0 are all right,
while status itself has been last checked @ line# 117 and it was the "right" 241h value !

Now I will investigate a bit about these trayOpen and media variables.

They come to CMscdex::GetDeviceStatus() from
GetMediaStatus(), but
surely not from this one :

bool GetMediaStatus (Bit8u subUnit, Bit8u& status);
they come instead from :

bool GetMediaStatus (Bit8u subUnit, bool& media, bool& changed, bool& trayOpen);

now this

bool CMscdex::GetMediaStatus(Bit8u subUnit, bool& media, bool& changed, bool& trayOpen)
{
if (subUnit>=numDrives) return false;
dinfo[subUnit].lastResult = cdrom[subUnit]->GetMediaTrayStatus(media,changed,trayOpen);
return dinfo[subUnit].lastResult;
};

just invokes cdrom[subUnit]->GetMediaTrayStatus(media,changed,trayOpen);

don't let me show you this time sdl's

CDROM_Interface_SDL::GetMediaTrayStatus()
which dwells in cdrom.cpp of course where you can check it but it poses no riddles imho, the crucial point of it being the line :

mediaPresent = (cd->status!=CD_TRAYEMPTY) && (cd->status!=CD_ERROR);

no, let me fly to much more enticing 🙄 ioctl
CDROM_Interface_Ioctl::GetMediaTrayStatus()

which is well worth reporting in all its appeal :

bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen)
{
// Seems not possible to get this values using ioctl...
int track1,track2;
TMSF leadOut;
// If we can read, there's a media
mediaPresent = GetAudioTracks(track1, track2, leadOut),
trayOpen = !mediaPresent;
mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr);
if (mediaChanged) {
// Open new media
Close(); Open();
};
// Save old values
oldLeadOut.min = leadOut.min;
oldLeadOut.sec = leadOut.sec;
oldLeadOut.fr = leadOut.fr;
// always success
return true;
};

Notice that bool trayOpen just gets toggled by bool mediaPresent
trayOpen = !mediaPresent;
it's mediaPresent who leads, and it comes from

CDROM_Interface_Ioctl::GetAudioTracks() of course

bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) 
{
// Open();
CDROM_TOC toc;
DWORD byteCount;
BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), &byteCount,NULL);
// Close();
if (!bStat) return false;

stTrack = toc.FirstTrack;
endTrack = toc.LastTrack;
leadOut.min = toc.TrackData[endTrack].Address[1];
leadOut.sec = toc.TrackData[endTrack].Address[2];
leadOut.fr = toc.TrackData[endTrack].Address[3];
return true;
};

see ?

	CDROM_TOC toc;
DWORD byteCount;
BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), &byteCount,NULL);

are we finally before the ultimate IOCTL_CDROM_READ_TOC\DeviceIoControl() misfire ?

How upwards can you go, I'm asking you ???

Secondly, have you noticed this thing in
CDROM_Interface_Ioctl::GetMediaTrayStatus() up there :

mediaPresent = GetAudioTracks(track1, track2, leadOut),
trayOpen = !mediaPresent;

am I just too tired now, or there's an obnoxious bug after "leadOut)," ????
Where's that instruction ending ?
What if this is messing up the critical mediaPresent value ???

So far, the outcome of comparing ioctl vista and noioctl vista.

The comparison between

ioctl xp and ioctl vista

shows a bunch of functions not being called at all in ioctl vista as may be predictable.
There's really too many of them to be reported here by me, just diffmerge them and see.

It's only logical that they should explode after the moment music breaks in ioctl vista (line #284, remember ?), before that the diffs are there but seem to me pretty unrelevant to the cdaudio play issue.
After that, they are legion.

CMscdex::StopAudio() seems to be the first to go, not that my log msg there gets weird, it just won't show up, that means that
CDROM_Interface_Ioctl::StopAudio() has failed completely and
return bStat>0;
has returned 0x0.

Then PlayAudioSector() never catches up, then GetAudioStatus() and GetDeviceStatus() in a great cascade.

What do you say, wd (and Qbix and others, of course), was this worth my efforts 😖 ?

Something useful to come up ?

--------------------------

Friends come and go, enemies build up (by an Onymous)

Attachments

  • Filename
    ioctl vista log.txt
    File size
    18.67 KiB
    Downloads
    318 downloads
    File license
    Fair use/fair dealing exception
  • Filename
    noioctl vista log.txt
    File size
    16.51 KiB
    Downloads
    355 downloads
    File license
    Fair use/fair dealing exception
Last edited by gidierre on 2008-04-10, 18:55. Edited 4 times in total.

Reply 30 of 48, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

am I just too tired now, or there's an obnoxious bug after "leadOut)," ????

Looks indeed buggy, but works fine (multiple variable setting).

But nice that we are finally at the TOC function again 😀

Reply 32 of 48, by MiniMax

User metadata
Rank Moderator
Rank
Moderator

Edit: wd is right, and I am a n00b 😀

Last edited by MiniMax on 2008-04-10, 19:35. Edited 1 time in total.

DOSBox 60 seconds guide | How to ask questions
_________________
Lenovo M58p | Core 2 Quad Q8400 @ 2.66 GHz | Radeon R7 240 | LG HL-DT-ST DVDRAM GH40N | Fedora 32

Reply 34 of 48, by gidierre

User metadata
Rank Member
Rank
Member

my fellow forummates,

while I was at it,
I thought I might as well report here a short listing of the
CD-ROM I/O Control Codes that will fail under Vista,

as gathered after browsing
http://msdn2.microsoft.com/en-us/library/ms803697.aspx

maybe someone cares to know that they are

IOCTL_CDROM_GET_VOLUME

IOCTL_CDROM_SET_VOLUME

IOCTL_CDROM_READ_TOC

IOCTL_CDROM_READ_Q_CHANNEL

IOCTL_CDROM_PLAY_AUDIO_MSF

IOCTL_CDROM_SEEK_AUDIO_MSF

IOCTL_CDROM_PAUSE_AUDIO

IOCTL_CDROM_RESUME_AUDIO

IOCTL_CDROM_STOP_AUDIO

go figure how come some applications go bananas with Windows Vista 🙄

OTOH,

IOCTL_CDROM_READ_TOC_EX

and

IOCTL_CDROM_RAW_READ

don't appear to be deprecateware, for some reason.

Reply 35 of 48, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Uhm that's just what the msdn says, up to now a lot seems just deprecated
but fully working, at least according to the information you posted and that
is gathered elsewhere.
For example the TOC function seems to be working just fine afaik.

Reply 36 of 48, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I did some debugging myself on it and it actually appears to work 100% aside from the small detail that there is no volume coming from the speakers. The play audio IOCTL returns success, the drive is spinning (etc etc)
Just no sound 🙁

Water flows down the stream
How to ask questions the smart way!

Reply 37 of 48, by gidierre

User metadata
Rank Member
Rank
Member

Like, DeviceIoControl() returns TRUE, which is not.

Silent fail, so did Dege describe this behavior to me.

-----------------------------------

Smile, tomorrow it's gonna grow worse (still by an Onymous)

Last edited by gidierre on 2008-06-04, 21:27. Edited 1 time in total.

Reply 39 of 48, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

i wouldn't call it silent fail as the drive is spinning as if it is playing music.

gidierre: Is you cdrom connected analog to your soundcard ?

Water flows down the stream
How to ask questions the smart way!