#include "OpticalDrive.hpp" #include "IoCtl.hpp" #include "SDL.h" #ifdef _WIN32 #include #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* 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::ListOpticalDrives() { std::vector* drives = new std::vector(); #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; } }