DumpDVD/DumpDVD/Scsi/OpticalDrive.cpp

132 lines
3.7 KiB
C++

#include "OpticalDrive.hpp"
#include "IoCtl.hpp"
#include "SDL.h"
#ifdef _WIN32
#include <Windows.h>
#endif
#define BUFFER_SIZE (0x1000)
#define NODISC ("NO DISC")
namespace Li::Scsi {
void OpticalDrive::getDriveInformation(std::string drv) {
#ifdef _WIN32
this->drivePath = drv.substr(0, drv.size() - 1);
std::wstring wdrive = std::wstring(this->drivePath.begin(), this->drivePath.end());
WCHAR* wChrVolumeName = new WCHAR[BUFFER_SIZE];
if (!GetVolumeInformation(wdrive.c_str(), wChrVolumeName, BUFFER_SIZE, NULL, NULL, NULL, NULL, NULL))
{
this->volumeName = NODISC;
this->discInDrive = false;
}
else {
std::wstring wVolumeName = std::wstring(wChrVolumeName);
this->volumeName = std::string(wVolumeName.begin(), wVolumeName.end());
this->discInDrive = true;
}
delete wChrVolumeName;
#else
#error no way to get optical drive information on this platform
#endif
}
OpticalDrive::OpticalDrive(std::string drv) {
this->getDriveInformation(drv);
if (this->discInDrive) {
IoCtl* ctl = new IoCtl(this->drivePath);
this->supportedSpeeds = ctl->GetSupportedReadSpeeds();
this->sectors = ctl->GetTotalSectors();
this->hasCss = dvdcss_is_scrambled(ctl->GetDvdCssHandle());
if (this->hasCss) {
std::byte* dkey = (std::byte*)dvdcss_get_cur_disckey(ctl->GetDvdCssHandle());
memcpy(this->discKey, dkey, sizeof(OpticalDrive::discKey));
}
else {
memset(this->discKey, 0, sizeof(OpticalDrive::discKey));
}
delete ctl;
}
}
OpticalDrive::~OpticalDrive() {
if(this->discInDrive)
delete this->supportedSpeeds;
}
std::vector<uint32_t>* OpticalDrive::SupportedSpeeds() {
return this->supportedSpeeds;
}
std::string OpticalDrive::VolumeName() {
return this->volumeName;
}
std::string OpticalDrive::DrivePath() {
return this->drivePath;
}
bool OpticalDrive::HasCss() {
return this->hasCss;
}
std::byte* OpticalDrive::DiscKey() {
return this->discKey;
}
uint32_t OpticalDrive::Sectors() {
return this->sectors;
}
bool OpticalDrive::DiscInDrive() {
return this->discInDrive;
}
std::vector<OpticalDrive*>* OpticalDrive::ListOpticalDrives() {
std::vector<OpticalDrive*>* drives = new std::vector<OpticalDrive*>();
#ifdef _WIN32
WCHAR* drivesList = new WCHAR[BUFFER_SIZE];
memset(drivesList, 0x00, sizeof(drivesList));
if (GetLogicalDriveStrings(BUFFER_SIZE, drivesList) != 0) {
WCHAR* curDrive = drivesList;
while (*curDrive != '\0') {
UINT driveType = GetDriveType(curDrive);
if (driveType == DRIVE_CDROM) {
std::wstring wDrive = std::wstring(curDrive);
std::string drive = std::string(wDrive.begin(), wDrive.end());
OpticalDrive* opticalDrive = new OpticalDrive(drive);
drives->push_back(opticalDrive);
}
curDrive += lstrlen(curDrive) + 1;
}
}
delete drivesList;
#else
/*
* Looks like SDL cdrom support got removed at some point .. oh well
*
// Use SDL
int numCdDrives = SDL_CDNumDrives();
for (int i = 0; i < numCdDrives; i++) {
OpticalDrive* opticalDrive = new OpticalDrive(SDL_CDName(i));
drives->push_back(opticalDrive);
}
*/
#error No way to list optical drives on this platform!
#endif
return drives;
}
}