mirror of https://github.com/PCSX2/pcsx2.git
cdvdgigaherz: Reduce disc info ioctl calls
It's rather unnecessary to use the same ioctls multiple times per disc when the info returned doesn't change. Just use each ioctl once and read/calculate all the necessary info all at onace. This also fixes an issue where the IOCTL_DVD_START_SESSION ioctl is repeatedly used if the returned session ID is 0. The previous code assumed that 0 was not a valid session ID and would repeatedly use the ioctl to obtain a non-zero session ID. However, 0 is a valid session ID, and it seems IOCTL_DVD_START_SESSION can repeatedly return a 0 session ID even if the corresponding IOCTL_DVD_END_SESSION has not been called. In our case, a DVD session is only necessary for DVD detection and reading the physical format information. This fix seems to alter drive speed behaviour.
This commit is contained in:
parent
f8e474a1c5
commit
1f60e3101e
|
@ -17,8 +17,12 @@
|
||||||
#define __CDVD_H__
|
#define __CDVD_H__
|
||||||
|
|
||||||
#define _WIN32_WINNT 0x0600
|
#define _WIN32_WINNT 0x0600
|
||||||
|
#define NOMINMAX
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#define CDVDdefs
|
#define CDVDdefs
|
||||||
#include <PS2Edefs.h>
|
#include <PS2Edefs.h>
|
||||||
|
@ -62,38 +66,32 @@ extern toc_data cdtoc;
|
||||||
|
|
||||||
class IOCtlSrc
|
class IOCtlSrc
|
||||||
{
|
{
|
||||||
IOCtlSrc(IOCtlSrc &);
|
IOCtlSrc(const IOCtlSrc &) = delete;
|
||||||
|
IOCtlSrc &operator=(const IOCtlSrc &) = delete;
|
||||||
|
|
||||||
HANDLE m_device;
|
HANDLE m_device = INVALID_HANDLE_VALUE;
|
||||||
|
std::string m_filename;
|
||||||
bool OpenOK;
|
bool OpenOK;
|
||||||
|
|
||||||
char sectorbuffer[32 * 2048];
|
bool m_disc_ready = false;
|
||||||
|
s32 m_media_type = 0;
|
||||||
char fName[256];
|
u32 m_sectors = 0;
|
||||||
|
u32 m_layer_break = 0;
|
||||||
DWORD sessID;
|
|
||||||
|
|
||||||
bool tocCached;
|
|
||||||
char tocCacheData[2048];
|
char tocCacheData[2048];
|
||||||
|
|
||||||
bool mediaTypeCached;
|
bool ReadDVDInfo();
|
||||||
int mediaType;
|
bool ReadCDInfo();
|
||||||
|
bool RefreshDiscInfo();
|
||||||
bool discSizeCached;
|
|
||||||
s32 discSize;
|
|
||||||
|
|
||||||
bool layerBreakCached;
|
|
||||||
s32 layerBreak;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IOCtlSrc(const char *fileName);
|
IOCtlSrc(const char *filename);
|
||||||
~IOCtlSrc();
|
~IOCtlSrc();
|
||||||
|
|
||||||
s32 GetSectorCount();
|
u32 GetSectorCount();
|
||||||
s32 ReadTOC(char *toc, int size);
|
s32 ReadTOC(char *toc, size_t size);
|
||||||
s32 ReadSectors2048(u32 sector, u32 count, char *buffer);
|
s32 ReadSectors2048(u32 sector, u32 count, char *buffer);
|
||||||
s32 ReadSectors2352(u32 sector, u32 count, char *buffer);
|
s32 ReadSectors2352(u32 sector, u32 count, char *buffer);
|
||||||
s32 GetLayerBreakAddress();
|
u32 GetLayerBreakAddress();
|
||||||
|
|
||||||
s32 GetMediaType();
|
s32 GetMediaType();
|
||||||
void SetSpindleSpeed(bool restore_defaults);
|
void SetSpindleSpeed(bool restore_defaults);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
/* PCSX2 - PS2 Emulator for PCs
|
||||||
|
* Copyright (C) 2016 PCSX2 Dev Team
|
||||||
* Copyright (C) 2002-2014 David Quintana [gigaherz]
|
* Copyright (C) 2002-2014 David Quintana [gigaherz]
|
||||||
*
|
*
|
||||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||||
|
@ -26,47 +27,12 @@
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
s32 IOCtlSrc::Reopen()
|
IOCtlSrc::IOCtlSrc(const char *filename)
|
||||||
|
: m_filename(filename)
|
||||||
{
|
{
|
||||||
if (m_device != INVALID_HANDLE_VALUE) {
|
|
||||||
DWORD size;
|
|
||||||
DeviceIoControl(m_device, IOCTL_DVD_END_SESSION, &sessID, sizeof(DVD_SESSION_ID), NULL, 0, &size, NULL);
|
|
||||||
CloseHandle(m_device);
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD size;
|
|
||||||
|
|
||||||
OpenOK = false;
|
|
||||||
// SPTI only works if the device is opened with GENERIC_WRITE access.
|
|
||||||
m_device = CreateFile(fName, GENERIC_READ | GENERIC_WRITE,
|
|
||||||
FILE_SHARE_READ, nullptr, OPEN_EXISTING,
|
|
||||||
FILE_FLAG_SEQUENTIAL_SCAN, nullptr);
|
|
||||||
if (m_device == INVALID_HANDLE_VALUE)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Dual layer DVDs cannot read from layer 1 without this ioctl
|
|
||||||
DeviceIoControl(m_device, FSCTL_ALLOW_EXTENDED_DASD_IO, nullptr, 0, nullptr, 0, &size, nullptr);
|
|
||||||
|
|
||||||
// FIXME: 0 is a valid session id, but the code assumes that it isn't.
|
|
||||||
sessID = 0;
|
|
||||||
DeviceIoControl(m_device, IOCTL_DVD_START_SESSION, NULL, 0, &sessID, sizeof(DVD_SESSION_ID), &size, NULL);
|
|
||||||
|
|
||||||
tocCached = false;
|
|
||||||
mediaTypeCached = false;
|
|
||||||
discSizeCached = false;
|
|
||||||
layerBreakCached = false;
|
|
||||||
|
|
||||||
OpenOK = true;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
IOCtlSrc::IOCtlSrc(const char *fileName)
|
|
||||||
{
|
|
||||||
m_device = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
strcpy_s(fName, 256, fileName);
|
|
||||||
|
|
||||||
Reopen();
|
Reopen();
|
||||||
SetSpindleSpeed(false);
|
SetSpindleSpeed(false);
|
||||||
}
|
}
|
||||||
|
@ -75,120 +41,30 @@ IOCtlSrc::~IOCtlSrc()
|
||||||
{
|
{
|
||||||
if (OpenOK) {
|
if (OpenOK) {
|
||||||
SetSpindleSpeed(true);
|
SetSpindleSpeed(true);
|
||||||
DWORD size;
|
|
||||||
DeviceIoControl(m_device, IOCTL_DVD_END_SESSION, &sessID, sizeof(DVD_SESSION_ID), NULL, 0, &size, NULL);
|
|
||||||
|
|
||||||
CloseHandle(m_device);
|
CloseHandle(m_device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mycrap
|
s32 IOCtlSrc::Reopen()
|
||||||
{
|
{
|
||||||
DWORD shit;
|
if (m_device != INVALID_HANDLE_VALUE)
|
||||||
DVD_LAYER_DESCRIPTOR ld;
|
CloseHandle(m_device);
|
||||||
// The IOCTL_DVD_READ_STRUCTURE expects a size of at least 22 bytes when
|
|
||||||
// reading the dvd physical layer descriptor
|
|
||||||
// 4 bytes header
|
|
||||||
// 17 bytes for the layer descriptor
|
|
||||||
// 1 byte of the media specific data for no reason whatsoever...
|
|
||||||
UCHAR fixup;
|
|
||||||
};
|
|
||||||
|
|
||||||
DVD_READ_STRUCTURE dvdrs;
|
|
||||||
mycrap dld;
|
|
||||||
CDROM_READ_TOC_EX tocrq = {0};
|
|
||||||
|
|
||||||
s32 IOCtlSrc::GetSectorCount()
|
|
||||||
{
|
|
||||||
if (discSizeCached)
|
|
||||||
return discSize;
|
|
||||||
|
|
||||||
DWORD size;
|
DWORD size;
|
||||||
GET_LENGTH_INFORMATION info;
|
|
||||||
if (DeviceIoControl(m_device, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &info, sizeof(info), &size, NULL)) {
|
|
||||||
discSizeCached = true;
|
|
||||||
discSize = (s32)(info.Length.QuadPart / 2048);
|
|
||||||
return discSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&tocrq, 0, sizeof(CDROM_READ_TOC_EX));
|
OpenOK = false;
|
||||||
tocrq.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC;
|
// SPTI only works if the device is opened with GENERIC_WRITE access.
|
||||||
tocrq.Msf = 1;
|
m_device = CreateFile(m_filename.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||||
tocrq.SessionTrack = 1;
|
FILE_SHARE_READ, nullptr, OPEN_EXISTING,
|
||||||
|
FILE_FLAG_SEQUENTIAL_SCAN, nullptr);
|
||||||
CDROM_TOC_FULL_TOC_DATA *ftd = (CDROM_TOC_FULL_TOC_DATA *)sectorbuffer;
|
if (m_device == INVALID_HANDLE_VALUE)
|
||||||
|
|
||||||
if (DeviceIoControl(m_device, IOCTL_CDROM_READ_TOC_EX, &tocrq, sizeof(tocrq), ftd, 2048, &size, NULL)) {
|
|
||||||
for (int i = 0; i < 101; i++) {
|
|
||||||
if (ftd->Descriptors[i].Point == 0xa2) {
|
|
||||||
if (ftd->Descriptors[i].SessionNumber == ftd->LastCompleteSession) {
|
|
||||||
int min = ftd->Descriptors[i].Msf[0];
|
|
||||||
int sec = ftd->Descriptors[i].Msf[1];
|
|
||||||
int frm = ftd->Descriptors[i].Msf[2];
|
|
||||||
|
|
||||||
discSizeCached = true;
|
|
||||||
discSize = (s32)MSF_TO_LBA(min, sec, frm);
|
|
||||||
return discSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dvdrs.BlockByteOffset.QuadPart = 0;
|
|
||||||
dvdrs.Format = DvdPhysicalDescriptor;
|
|
||||||
dvdrs.SessionId = sessID;
|
|
||||||
dvdrs.LayerNumber = 0;
|
|
||||||
if (DeviceIoControl(m_device, IOCTL_DVD_READ_STRUCTURE, &dvdrs, sizeof(dvdrs), &dld, sizeof(dld), &size, NULL) != 0) {
|
|
||||||
s32 sectors1 = _byteswap_ulong(dld.ld.EndDataSector) - _byteswap_ulong(dld.ld.StartingDataSector) + 1;
|
|
||||||
if (dld.ld.NumberOfLayers == 1) { // PTP, OTP
|
|
||||||
if (dld.ld.TrackPath == 0) { // PTP
|
|
||||||
dvdrs.LayerNumber = 1;
|
|
||||||
if (DeviceIoControl(m_device, IOCTL_DVD_READ_STRUCTURE, &dvdrs, sizeof(dvdrs), &dld, sizeof(dld), &size, nullptr) != 0) {
|
|
||||||
sectors1 += _byteswap_ulong(dld.ld.EndDataSector) - _byteswap_ulong(dld.ld.StartingDataSector) + 1;
|
|
||||||
}
|
|
||||||
} else { // OTP
|
|
||||||
// sectors = end_sector - (~end_sector_l0 & 0xFFFFFF) + end_sector_l0 - start_sector
|
|
||||||
dld.ld.EndLayerZeroSector = _byteswap_ulong(dld.ld.EndLayerZeroSector);
|
|
||||||
sectors1 += dld.ld.EndLayerZeroSector - (~dld.ld.EndLayerZeroSector & 0x00FFFFFF) + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
discSizeCached = true;
|
|
||||||
discSize = sectors1;
|
|
||||||
return discSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 IOCtlSrc::GetLayerBreakAddress()
|
|
||||||
{
|
|
||||||
DWORD size;
|
|
||||||
|
|
||||||
if (GetMediaType() < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (layerBreakCached)
|
// Required to read from layer 1 of Dual layer DVDs
|
||||||
return layerBreak;
|
DeviceIoControl(m_device, FSCTL_ALLOW_EXTENDED_DASD_IO, nullptr, 0, nullptr, 0, &size, nullptr);
|
||||||
|
|
||||||
dvdrs.BlockByteOffset.QuadPart = 0;
|
m_disc_ready = false;
|
||||||
dvdrs.Format = DvdPhysicalDescriptor;
|
OpenOK = true;
|
||||||
dvdrs.SessionId = sessID;
|
|
||||||
dvdrs.LayerNumber = 0;
|
|
||||||
if (DeviceIoControl(m_device, IOCTL_DVD_READ_STRUCTURE, &dvdrs, sizeof(dvdrs), &dld, sizeof(dld), &size, nullptr)) {
|
|
||||||
if (dld.ld.NumberOfLayers == 0) { // Single layer
|
|
||||||
layerBreak = 0;
|
|
||||||
} else if (dld.ld.TrackPath == 0) { // PTP
|
|
||||||
layerBreak = _byteswap_ulong(dld.ld.EndDataSector) - _byteswap_ulong(dld.ld.StartingDataSector);
|
|
||||||
} else { // OTP
|
|
||||||
layerBreak = _byteswap_ulong(dld.ld.EndLayerZeroSector) - _byteswap_ulong(dld.ld.StartingDataSector);
|
|
||||||
}
|
|
||||||
|
|
||||||
layerBreakCached = true;
|
|
||||||
return layerBreak;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if not a cd, and fails, assume single layer
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,74 +113,42 @@ void IOCtlSrc::SetSpindleSpeed(bool restore_defaults)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 IOCtlSrc::GetMediaType()
|
u32 IOCtlSrc::GetSectorCount()
|
||||||
{
|
{
|
||||||
DWORD size;
|
if (!m_disc_ready)
|
||||||
|
RefreshDiscInfo();
|
||||||
|
|
||||||
if (mediaTypeCached)
|
return m_sectors;
|
||||||
return mediaType;
|
|
||||||
|
|
||||||
memset(&tocrq, 0, sizeof(CDROM_READ_TOC_EX));
|
|
||||||
tocrq.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC;
|
|
||||||
tocrq.Msf = 1;
|
|
||||||
tocrq.SessionTrack = 1;
|
|
||||||
|
|
||||||
CDROM_TOC_FULL_TOC_DATA *ftd = (CDROM_TOC_FULL_TOC_DATA *)sectorbuffer;
|
|
||||||
|
|
||||||
if (DeviceIoControl(m_device, IOCTL_CDROM_READ_TOC_EX, &tocrq, sizeof(tocrq), ftd, 2048, &size, NULL)) {
|
|
||||||
mediaTypeCached = true;
|
|
||||||
mediaType = -1;
|
|
||||||
return mediaType;
|
|
||||||
}
|
|
||||||
|
|
||||||
dvdrs.BlockByteOffset.QuadPart = 0;
|
|
||||||
dvdrs.Format = DvdPhysicalDescriptor;
|
|
||||||
dvdrs.SessionId = sessID;
|
|
||||||
dvdrs.LayerNumber = 0;
|
|
||||||
if (DeviceIoControl(m_device, IOCTL_DVD_READ_STRUCTURE, &dvdrs, sizeof(dvdrs), &dld, sizeof(dld), &size, nullptr)) {
|
|
||||||
if (dld.ld.NumberOfLayers == 0) { // Single layer
|
|
||||||
mediaType = 0;
|
|
||||||
} else if (dld.ld.TrackPath == 0) { // PTP
|
|
||||||
mediaType = 1;
|
|
||||||
} else { // OTP
|
|
||||||
mediaType = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaTypeCached = true;
|
|
||||||
return mediaType;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if not a cd, and fails, assume single layer
|
|
||||||
mediaTypeCached = true;
|
|
||||||
mediaType = 0;
|
|
||||||
return mediaType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 IOCtlSrc::ReadTOC(char *toc, int msize)
|
u32 IOCtlSrc::GetLayerBreakAddress()
|
||||||
{
|
{
|
||||||
DWORD size = 0;
|
if (!m_disc_ready)
|
||||||
|
RefreshDiscInfo();
|
||||||
|
|
||||||
|
if (GetMediaType() < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return m_layer_break;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 IOCtlSrc::GetMediaType()
|
||||||
|
{
|
||||||
|
if (!m_disc_ready)
|
||||||
|
RefreshDiscInfo();
|
||||||
|
|
||||||
|
return m_media_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 IOCtlSrc::ReadTOC(char *toc, size_t size)
|
||||||
|
{
|
||||||
|
if (!m_disc_ready)
|
||||||
|
RefreshDiscInfo();
|
||||||
|
|
||||||
if (GetMediaType() >= 0)
|
if (GetMediaType() >= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!tocCached) {
|
memcpy(toc, tocCacheData, std::min(size, sizeof(tocCacheData)));
|
||||||
memset(&tocrq, 0, sizeof(CDROM_READ_TOC_EX));
|
|
||||||
tocrq.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC;
|
|
||||||
tocrq.Msf = 1;
|
|
||||||
tocrq.SessionTrack = 1;
|
|
||||||
|
|
||||||
if (!OpenOK)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int code = DeviceIoControl(m_device, IOCTL_CDROM_READ_TOC_EX, &tocrq, sizeof(tocrq), tocCacheData, 2048, &size, NULL);
|
|
||||||
|
|
||||||
if (code == 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
tocCached = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(toc, tocCacheData, min(2048, msize));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -398,6 +242,108 @@ s32 IOCtlSrc::ReadSectors2352(u32 sector, u32 count, char *buffer)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IOCtlSrc::ReadDVDInfo()
|
||||||
|
{
|
||||||
|
DWORD unused;
|
||||||
|
DVD_SESSION_ID session_id;
|
||||||
|
|
||||||
|
BOOL ret = DeviceIoControl(m_device, IOCTL_DVD_START_SESSION, nullptr, 0,
|
||||||
|
&session_id, sizeof(session_id), &unused, nullptr);
|
||||||
|
if (!ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 4 bytes header + 18 bytes layer descriptor - Technically you only need
|
||||||
|
// to read 17 bytes of the layer descriptor since bytes 17-2047 is for
|
||||||
|
// media specific information. However, Windows requires you to read at
|
||||||
|
// least 18 bytes of the layer descriptor or else the ioctl will fail. The
|
||||||
|
// media specific information seems to be empty, so there's no point reading
|
||||||
|
// any more than that.
|
||||||
|
std::array<u8, 22> buffer;
|
||||||
|
DVD_READ_STRUCTURE dvdrs{{0}, DvdPhysicalDescriptor, session_id, 0};
|
||||||
|
|
||||||
|
ret = DeviceIoControl(m_device, IOCTL_DVD_READ_STRUCTURE, &dvdrs, sizeof(dvdrs),
|
||||||
|
buffer.data(), buffer.size(), &unused, nullptr);
|
||||||
|
if (ret) {
|
||||||
|
auto &layer = *reinterpret_cast<DVD_LAYER_DESCRIPTOR *>(
|
||||||
|
reinterpret_cast<DVD_DESCRIPTOR_HEADER *>(buffer.data())->Data);
|
||||||
|
|
||||||
|
u32 start_sector = _byteswap_ulong(layer.StartingDataSector);
|
||||||
|
u32 end_sector = _byteswap_ulong(layer.EndDataSector);
|
||||||
|
|
||||||
|
if (layer.NumberOfLayers == 0) {
|
||||||
|
// Single layer
|
||||||
|
m_media_type = 0;
|
||||||
|
m_layer_break = 0;
|
||||||
|
m_sectors = end_sector - start_sector + 1;
|
||||||
|
} else if (layer.TrackPath == 0) {
|
||||||
|
// Dual layer, Parallel Track Path
|
||||||
|
dvdrs.LayerNumber = 1;
|
||||||
|
ret = DeviceIoControl(m_device, IOCTL_DVD_READ_STRUCTURE, &dvdrs,
|
||||||
|
sizeof(dvdrs), buffer.data(), buffer.size(), &unused, nullptr);
|
||||||
|
if (ret) {
|
||||||
|
u32 layer1_start_sector = _byteswap_ulong(layer.StartingDataSector);
|
||||||
|
u32 layer1_end_sector = _byteswap_ulong(layer.EndDataSector);
|
||||||
|
|
||||||
|
m_media_type = 1;
|
||||||
|
m_layer_break = end_sector - start_sector;
|
||||||
|
m_sectors = end_sector - start_sector + 1 + layer1_end_sector - layer1_start_sector + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Dual layer, Opposite Track Path
|
||||||
|
u32 end_sector_layer0 = _byteswap_ulong(layer.EndLayerZeroSector);
|
||||||
|
m_media_type = 2;
|
||||||
|
m_layer_break = end_sector_layer0 - start_sector;
|
||||||
|
m_sectors = end_sector_layer0 - start_sector + 1 + end_sector - (~end_sector_layer0 & 0xFFFFFFU) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceIoControl(m_device, IOCTL_DVD_END_SESSION, &session_id,
|
||||||
|
sizeof(session_id), nullptr, 0, &unused, nullptr);
|
||||||
|
|
||||||
|
return !!ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOCtlSrc::ReadCDInfo()
|
||||||
|
{
|
||||||
|
DWORD unused;
|
||||||
|
CDROM_READ_TOC_EX toc_ex{};
|
||||||
|
toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC;
|
||||||
|
toc_ex.Msf = 1;
|
||||||
|
toc_ex.SessionTrack = 1;
|
||||||
|
|
||||||
|
if (!DeviceIoControl(m_device, IOCTL_CDROM_READ_TOC_EX, &toc_ex,
|
||||||
|
sizeof(toc_ex), tocCacheData, sizeof(tocCacheData), &unused, nullptr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GET_LENGTH_INFORMATION info;
|
||||||
|
if (!DeviceIoControl(m_device, IOCTL_DISK_GET_LENGTH_INFO, nullptr, 0, &info,
|
||||||
|
sizeof(info), &unused, nullptr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_sectors = static_cast<u32>(info.Length.QuadPart / 2048);
|
||||||
|
m_media_type = -1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOCtlSrc::RefreshDiscInfo()
|
||||||
|
{
|
||||||
|
if (m_disc_ready)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
m_media_type = 0;
|
||||||
|
m_layer_break = 0;
|
||||||
|
m_sectors = 0;
|
||||||
|
|
||||||
|
if (!OpenOK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ReadDVDInfo() || ReadCDInfo())
|
||||||
|
m_disc_ready = true;
|
||||||
|
|
||||||
|
return m_disc_ready;
|
||||||
|
}
|
||||||
|
|
||||||
s32 IOCtlSrc::DiscChanged()
|
s32 IOCtlSrc::DiscChanged()
|
||||||
{
|
{
|
||||||
DWORD size = 0;
|
DWORD size = 0;
|
||||||
|
@ -408,22 +354,11 @@ s32 IOCtlSrc::DiscChanged()
|
||||||
int ret = DeviceIoControl(m_device, IOCTL_STORAGE_CHECK_VERIFY, NULL, 0, NULL, 0, &size, NULL);
|
int ret = DeviceIoControl(m_device, IOCTL_STORAGE_CHECK_VERIFY, NULL, 0, NULL, 0, &size, NULL);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
tocCached = false;
|
m_disc_ready = false;
|
||||||
mediaTypeCached = false;
|
|
||||||
discSizeCached = false;
|
|
||||||
layerBreakCached = false;
|
|
||||||
|
|
||||||
if (sessID != 0) {
|
|
||||||
DeviceIoControl(m_device, IOCTL_DVD_END_SESSION, &sessID, sizeof(DVD_SESSION_ID), NULL, 0, &size, NULL);
|
|
||||||
sessID = 0;
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sessID == 0) {
|
|
||||||
DeviceIoControl(m_device, IOCTL_DVD_START_SESSION, NULL, 0, &sessID, sizeof(DVD_SESSION_ID), &size, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue