mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-11-17 15:49:15 +01:00
290 lines
7.8 KiB
C++
290 lines
7.8 KiB
C++
/*
|
|
* Copyright (C) 2002-2007 The DOSBox Team
|
|
*
|
|
* 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
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
/* $Id: cdrom_ioctl_win32.cpp,v 1.14 2007/01/08 19:45:39 qbix79 Exp $ */
|
|
|
|
#if defined (WIN32)
|
|
|
|
// *****************************************************************
|
|
// Windows IOCTL functions (not suitable for 95/98/Me)
|
|
// *****************************************************************
|
|
|
|
#include <windows.h>
|
|
#include <io.h>
|
|
|
|
#if defined (_MSC_VER)
|
|
#include <ntddcdrm.h> // Ioctl stuff
|
|
#include <winioctl.h> // Ioctl stuff
|
|
#else
|
|
#include "ddk/ntddcdrm.h" // Ioctl stuff
|
|
#endif
|
|
|
|
#include "cdrom.h"
|
|
|
|
CDROM_Interface_Ioctl::CDROM_Interface_Ioctl()
|
|
{
|
|
pathname[0] = 0;
|
|
hIOCTL = INVALID_HANDLE_VALUE;
|
|
memset(&oldLeadOut,0,sizeof(oldLeadOut));
|
|
};
|
|
|
|
CDROM_Interface_Ioctl::~CDROM_Interface_Ioctl()
|
|
{
|
|
StopAudio();
|
|
Close();
|
|
};
|
|
|
|
bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc)
|
|
{
|
|
// FIXME : To Do
|
|
return true;
|
|
}
|
|
|
|
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;
|
|
};
|
|
|
|
bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr)
|
|
{
|
|
// 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;
|
|
|
|
attr = (toc.TrackData[track-1].Control << 4) & 0xEF;
|
|
start.min = toc.TrackData[track-1].Address[1];
|
|
start.sec = toc.TrackData[track-1].Address[2];
|
|
start.fr = toc.TrackData[track-1].Address[3];
|
|
return true;
|
|
};
|
|
|
|
bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos)
|
|
{
|
|
// 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;
|
|
|
|
attr = (sub.CurrentPosition.Control << 4) & 0xEF;
|
|
track = sub.CurrentPosition.TrackNumber;
|
|
index = sub.CurrentPosition.IndexNumber;
|
|
relPos.min = sub.CurrentPosition.TrackRelativeAddress[1];
|
|
relPos.sec = sub.CurrentPosition.TrackRelativeAddress[2];
|
|
relPos.fr = sub.CurrentPosition.TrackRelativeAddress[3];
|
|
absPos.min = sub.CurrentPosition.AbsoluteAddress[1];
|
|
absPos.sec = sub.CurrentPosition.AbsoluteAddress[2];
|
|
absPos.fr = sub.CurrentPosition.AbsoluteAddress[3];
|
|
|
|
return true;
|
|
};
|
|
|
|
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;
|
|
};
|
|
|
|
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;
|
|
};
|
|
|
|
bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long len)
|
|
{
|
|
// Open();
|
|
CDROM_PLAY_AUDIO_MSF audio;
|
|
DWORD byteCount;
|
|
// Start
|
|
unsigned long addr = start + 150;
|
|
audio.StartingF = (UCHAR)(addr%75); addr/=75;
|
|
audio.StartingS = (UCHAR)(addr%60);
|
|
audio.StartingM = (UCHAR)(addr/60);
|
|
// End
|
|
addr = start + len + 150;
|
|
audio.EndingF = (UCHAR)(addr%75); addr/=75;
|
|
audio.EndingS = (UCHAR)(addr%60);
|
|
audio.EndingM = (UCHAR)(addr/60);
|
|
|
|
BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF, &audio, sizeof(audio),
|
|
NULL, 0, &byteCount,NULL);
|
|
// Close();
|
|
return bStat>0;
|
|
};
|
|
|
|
bool CDROM_Interface_Ioctl::PauseAudio(bool resume)
|
|
{
|
|
// Open();
|
|
BOOL bStat;
|
|
DWORD byteCount;
|
|
if (resume) bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO, NULL, 0,
|
|
NULL, 0, &byteCount,NULL);
|
|
else bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO, NULL, 0,
|
|
NULL, 0, &byteCount,NULL);
|
|
// Close();
|
|
return bStat>0;
|
|
};
|
|
|
|
bool CDROM_Interface_Ioctl::StopAudio(void)
|
|
{
|
|
// Open();
|
|
BOOL bStat;
|
|
DWORD byteCount;
|
|
bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO, NULL, 0,
|
|
NULL, 0, &byteCount,NULL);
|
|
// Close();
|
|
return bStat>0;
|
|
};
|
|
|
|
bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload)
|
|
{
|
|
// Open();
|
|
BOOL bStat;
|
|
DWORD byteCount;
|
|
if (unload) bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_EJECT_MEDIA, NULL, 0,
|
|
NULL, 0, &byteCount,NULL);
|
|
else bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_LOAD_MEDIA, NULL, 0,
|
|
NULL, 0, &byteCount,NULL);
|
|
// Close();
|
|
return bStat>0;
|
|
};
|
|
|
|
bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num)
|
|
{
|
|
BOOL bStat;
|
|
DWORD byteCount = 0;
|
|
|
|
// Open();
|
|
|
|
Bitu buflen = raw ? num*RAW_SECTOR_SIZE : num*COOKED_SECTOR_SIZE;
|
|
Bit8u* bufdata = new Bit8u[buflen];
|
|
|
|
if (!raw) {
|
|
// Cooked
|
|
int success = 0;
|
|
DWORD newPos = SetFilePointer(hIOCTL, sector*COOKED_SECTOR_SIZE, 0, FILE_BEGIN);
|
|
if (newPos != 0xFFFFFFFF) success = ReadFile(hIOCTL, bufdata, buflen, &byteCount, NULL);
|
|
bStat = (success!=0);
|
|
} else {
|
|
// Raw
|
|
RAW_READ_INFO in;
|
|
in.DiskOffset.LowPart = sector;
|
|
in.DiskOffset.HighPart = 0;
|
|
in.SectorCount = num;
|
|
in.TrackMode = CDDA;
|
|
bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in),
|
|
bufdata, buflen, &byteCount,NULL);
|
|
}
|
|
// Close();
|
|
|
|
MEM_BlockWrite(buffer,bufdata,buflen);
|
|
delete[] bufdata;
|
|
|
|
return (byteCount==buflen) && (bStat>0);
|
|
}
|
|
|
|
bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD)
|
|
{
|
|
if (GetDriveType(path)==DRIVE_CDROM) {
|
|
char letter [3] = { 0, ':', 0 };
|
|
letter[0] = path[0];
|
|
strcpy(pathname,"\\\\.\\");
|
|
strcat(pathname,letter);
|
|
if (Open()) {
|
|
// Close();
|
|
return true;
|
|
};
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CDROM_Interface_Ioctl::Open(void)
|
|
{
|
|
hIOCTL = CreateFile(pathname, // drive to open
|
|
GENERIC_READ, // read access
|
|
FILE_SHARE_READ | // share mode
|
|
FILE_SHARE_WRITE,
|
|
NULL, // default security attributes
|
|
OPEN_EXISTING, // disposition
|
|
0, // file attributes
|
|
NULL); // do not copy file attributes
|
|
return (hIOCTL!=INVALID_HANDLE_VALUE);
|
|
};
|
|
|
|
void CDROM_Interface_Ioctl::Close(void)
|
|
{
|
|
CloseHandle(hIOCTL);
|
|
};
|
|
|
|
#endif
|