From ab8bd004fd34e48790c7ad0de51d571ccf77f73d Mon Sep 17 00:00:00 2001
From: Li
Date: Fri, 17 Mar 2023 21:23:19 +1300
Subject: [PATCH] Fix stuff
---
DumpDVD/Dvd/DvdRipper.cpp | 88 ++++++++++++++++++++++++++++-------
DumpDVD/Dvd/DvdRipper.hpp | 9 ++--
DumpDVD/Dvd/TitleKey.cpp | 36 +++++++++-----
DumpDVD/Dvd/TitleKey.hpp | 3 +-
DumpDVD/Gui/DumpDVD.cpp | 71 ++++++++++++++++------------
DumpDVD/Gui/DumpDVD.hpp | 1 +
DumpDVD/Gui/SDL.cpp | 11 ++++-
DumpDVD/Scsi/IoCtl.cpp | 17 +++++++
DumpDVD/Scsi/OpticalDrive.cpp | 34 ++++++++++++++
DumpDVD/Scsi/OpticalDrive.hpp | 5 ++
DumpDVD/Utils.cpp | 21 +++++++++
DumpDVD/Utils.hpp | 1 +
12 files changed, 231 insertions(+), 66 deletions(-)
diff --git a/DumpDVD/Dvd/DvdRipper.cpp b/DumpDVD/Dvd/DvdRipper.cpp
index fc6dfa5..a651577 100644
--- a/DumpDVD/Dvd/DvdRipper.cpp
+++ b/DumpDVD/Dvd/DvdRipper.cpp
@@ -33,13 +33,17 @@ namespace Li::Dvd {
}
std::byte* DvdRipper::GetDiscKey() {
- return this->discKey;
+ return this->drive->DiscKey();
}
std::byte* DvdRipper::GetTitleKey() {
return this->titleKey;
}
+ bool DvdRipper::Decrypt() {
+ return this->decrypt;
+ }
+
bool DvdRipper::Done() {
return this->done;
}
@@ -54,12 +58,12 @@ namespace Li::Dvd {
for (int i = 0; i < toRead; i++) {
for (int retry = 0; retry < 10; retry++) {
memset(this->tmpBuffer, 0x00, DVDCSS_BLOCK_SIZE);
- int dataRd = dvdcss_read(driveIoCtl->GetDvdCssHandle(), this->tmpBuffer, 1, DVDCSS_READ_DECRYPT);
+ int dataRd = dvdcss_read(driveIoCtl->GetDvdCssHandle(), this->tmpBuffer, 1, (this->decrypt ? DVDCSS_READ_DECRYPT : DVDCSS_NOFLAGS));
if (dataRd < 0) {
- dvdcss_seek(driveIoCtl->GetDvdCssHandle(), this->sectorsReadSoFar, DVDCSS_SEEK_KEY);
+ dvdcss_seek(driveIoCtl->GetDvdCssHandle(), this->sectorsReadSoFar, (this->decrypt ? DVDCSS_SEEK_KEY : DVDCSS_NOFLAGS) );
if (retry+1 >= 10)
- dvdcss_seek(driveIoCtl->GetDvdCssHandle(), this->sectorsReadSoFar + 1, DVDCSS_SEEK_KEY);
+ dvdcss_seek(driveIoCtl->GetDvdCssHandle(), this->sectorsReadSoFar + 1, (this->decrypt ? DVDCSS_SEEK_KEY : DVDCSS_NOFLAGS));
continue; // retry
}
@@ -80,7 +84,7 @@ namespace Li::Dvd {
}
- void DvdRipper::readSectors() {
+ void DvdRipper::readCssSectors() {
do {
int toRead = this->sectorsAtOnce;
if ((this->fileReadSoFar + toRead) > this->fileRemain) {
@@ -120,7 +124,7 @@ namespace Li::Dvd {
this->fileReadSoFar = 0;
- this->readSectors();
+ this->readCssSectors();
}
void DvdRipper::readFileSectors() {
@@ -135,21 +139,63 @@ namespace Li::Dvd {
this->fileReadSoFar = 0;
- this->readSectors();
+ this->readCssSectors();
+ }
+
+ void DvdRipper::readUnprotectedSectors() {
+ do {
+ int toRead = this->sectorsAtOnce;
+ if ((this->sectorsReadSoFar + toRead) > this->drive->Sectors()) {
+ toRead = this->drive->Sectors() - this->sectorsReadSoFar;
+ }
+
+ int numRead = dvdcss_read(this->driveIoCtl->GetDvdCssHandle(), this->tmpBuffer, toRead, DVDCSS_NOFLAGS);
+
+ if (dvdcss_was_error(driveIoCtl->GetDvdCssHandle())) {
+ this->errorMsg = std::string(dvdcss_error(driveIoCtl->GetDvdCssHandle()));
+ }
+ if (numRead < 0) { // Handle bad sectors
+ dvdcss_seek(driveIoCtl->GetDvdCssHandle(), this->sectorsReadSoFar, DVDCSS_NOFLAGS);
+ read1SectorATimeSkippingBadSectors(toRead);
+ }
+ else {
+ this->iso->write((const char*)this->tmpBuffer, DVDCSS_BLOCK_SIZE * numRead);
+ this->sectorsReadSoFar += numRead;
+ this->fileReadSoFar += numRead;
+ }
+
+ } while (this->sectorsReadSoFar < this->drive->Sectors() && this->keepRunning);
}
void DvdRipper::ripThread() {
this->sectorsReadSoFar = 0;
- Li::Dvd::TitleKey::GetTitleKeys(driveIoCtl->GetDvdCssHandle());
- dvdcss_seek(driveIoCtl->GetDvdCssHandle(), 0, DVDCSS_SEEK_KEY);
- this->inFile = Li::Dvd::TitleKey::IsSectorInFile(this->sectorsReadSoFar);
+ // due to how libdvdcss works, you can only actually decrypt a dvd sector
+ // if you seek directly at it or call dvdcss_title on the sector containing the start of the encrypted title file
+ // so, i have to actually parse the disc file system, in order to find all those
+ //
+ if (this->decrypt) {
+ Li::Dvd::TitleKey::FindTitleKeys(driveIoCtl->GetDvdCssHandle());
+ dvdcss_seek(driveIoCtl->GetDvdCssHandle(), 0, DVDCSS_SEEK_KEY);
+ this->inFile = Li::Dvd::TitleKey::IsSectorInFile(this->sectorsReadSoFar);
+ }
do {
- if (this->inFile)
- this->readFileSectors(); // read & decrypt all files (including those associated w the filesystem)
- else
- this->readNonFileSectors(); // read the data not associated with any file on the filesystem.
+ if (this->decrypt) {
+ if (this->inFile) {
+ // read & decrypt all files (including those associated w the filesystem)
+ this->readFileSectors();
+ }
+ else {
+ // read the data not associated with any file on the filesystem.
+ this->readNonFileSectors();
+ }
+ }
+ else {
+ // for non scrambled dvds, just read every sector one after another.
+ this->readUnprotectedSectors();
+ }
+
} while (this->sectorsReadSoFar < this->drive->Sectors() && this->keepRunning);
@@ -190,16 +236,22 @@ namespace Li::Dvd {
}
}
- void DvdRipper::StartRip(uint32_t driveSpeed) {
+ void DvdRipper::StartRip(uint32_t driveSpeed, bool cssDecrypt) {
this->driveIoCtl = new Li::Scsi::IoCtl(this->drive->DrivePath());
this->driveIoCtl->AllowReadingPastDisc();
this->driveIoCtl->SetDriveSpeed(driveSpeed, driveSpeed);
this->driveIoCtl->ExclusiveLockDrive();
- this->discKey = (std::byte*)dvdcss_get_cur_disckey(this->driveIoCtl->GetDvdCssHandle());
- dvdcss_title(this->driveIoCtl->GetDvdCssHandle(), 0);
- this->titleKey = (std::byte*)dvdcss_get_cur_titlekey(this->driveIoCtl->GetDvdCssHandle());
+ this->decrypt = cssDecrypt;
+ if (!dvdcss_is_scrambled(this->driveIoCtl->GetDvdCssHandle())) {
+ this->decrypt = false;
+ }
+
+ if (this->decrypt) {
+ dvdcss_title(this->driveIoCtl->GetDvdCssHandle(), 0);
+ this->titleKey = (std::byte*)dvdcss_get_cur_titlekey(this->driveIoCtl->GetDvdCssHandle());
+ }
this->iso = new std::ofstream(this->outputPath, std::ios::binary);
this->keepRunning = true;
diff --git a/DumpDVD/Dvd/DvdRipper.hpp b/DumpDVD/Dvd/DvdRipper.hpp
index 88f5378..1abda7e 100644
--- a/DumpDVD/Dvd/DvdRipper.hpp
+++ b/DumpDVD/Dvd/DvdRipper.hpp
@@ -27,12 +27,12 @@ namespace Li::Dvd {
std::thread* ripinThread;
bool keepRunning;
+ bool decrypt;
std::ofstream* iso;
std::byte* tmpBuffer;
std::byte* titleKey;
- std::byte* discKey;
Li::Scsi::IoCtl* driveIoCtl;
Li::Scsi::OpticalDrive* drive;
@@ -40,7 +40,9 @@ namespace Li::Dvd {
void readNonFileSectors();
void readFileSectors();
- void readSectors();
+ void readUnprotectedSectors();
+ void readCssSectors();
+
int read1SectorATimeSkippingBadSectors(int toRead);
public:
DvdRipper(Li::Scsi::OpticalDrive* opticalDrive, std::string outputISO, uint32_t sectorsAtOnce);
@@ -53,6 +55,7 @@ namespace Li::Dvd {
uint32_t FileSoFar();
uint32_t FileLen();
+ bool Decrypt();
std::byte* GetTitleKey();
std::byte* GetDiscKey();
@@ -60,7 +63,7 @@ namespace Li::Dvd {
bool Error();
std::string ErrorMessage();
- void StartRip(uint32_t driveSpeed);
+ void StartRip(uint32_t driveSpeed, bool decryptCss);
void EndRip();
};
}
diff --git a/DumpDVD/Dvd/TitleKey.cpp b/DumpDVD/Dvd/TitleKey.cpp
index b6860c2..a1d6343 100644
--- a/DumpDVD/Dvd/TitleKey.cpp
+++ b/DumpDVD/Dvd/TitleKey.cpp
@@ -11,6 +11,8 @@ namespace Li::Dvd {
static std::vector sectorsList;
static dvdcss_t drv;
+ static int depth = 0;
+
bool TitleKey::readSector(l9660_fs* fs, void* buf, uint32_t sector) {
dvdcss_seek(drv, sector, DVDCSS_SEEK_KEY);
@@ -58,10 +60,16 @@ namespace Li::Dvd {
}
- void readDir(l9660_dir* dir) {
- while (true) {
+ bool TitleKey::readDir(l9660_dir* dir, int depth=0) {
+
+ if (depth > 10) return false;
+
+ bool success = true;
+ for(int cnt = 0; cnt < 90000; ++cnt) {
+ if (cnt >= 90000) return false;
+
l9660_dirent* dent;
- l9660_status status = l9660_readdir(dir, &dent);
+ if (l9660_readdir(dir, &dent) != L9660_OK) return false;
if (dent == nullptr)
break;
@@ -69,13 +77,12 @@ namespace Li::Dvd {
if (dent->name_len < 2)
continue;
-
uint32_t cSector = *(uint32_t*)dent->sector.le;
if ((dent->flags & DENT_ISDIR) != 0) {
l9660_dir ndir;
- l9660_opendirat(&ndir, dir, dent->name);
- readDir(&ndir);
+ if (l9660_opendirat(&ndir, dir, dent->name) != L9660_OK) return false;
+ success = readDir(&ndir, depth + 1);
}
else if (TitleKey::GetSectorInfo(cSector) == nullptr) {
sectorInfo* file = new sectorInfo();
@@ -98,11 +105,14 @@ namespace Li::Dvd {
delete file;
}
}
-
+
}
+
+
+ return success;
}
- std::vector TitleKey::GetTitleKeys(dvdcss_t drive) {
+ bool TitleKey::FindTitleKeys(dvdcss_t drive) {
drv = drive;
sectorsList = std::vector();
@@ -110,11 +120,13 @@ namespace Li::Dvd {
l9660_fs isoFs;
l9660_status status;
- status = l9660_openfs(&isoFs, TitleKey::readSector);
- status = l9660_fs_open_root(&rootDir, &isoFs);
- readDir(&rootDir);
+ if (l9660_openfs(&isoFs, TitleKey::readSector) == L9660_OK) {
+ if (l9660_fs_open_root(&rootDir, &isoFs) == L9660_OK) {
+ return TitleKey::readDir(&rootDir);
+ }
+ }
- return sectorsList;
+ return false;
}
void TitleKey::FreeMemory() {
diff --git a/DumpDVD/Dvd/TitleKey.hpp b/DumpDVD/Dvd/TitleKey.hpp
index 4788c78..994809b 100644
--- a/DumpDVD/Dvd/TitleKey.hpp
+++ b/DumpDVD/Dvd/TitleKey.hpp
@@ -13,8 +13,9 @@ namespace Li::Dvd {
class TitleKey {
private:
static bool readSector(l9660_fs* fs, void* buf, uint32_t sector);
+ static bool readDir(l9660_dir* dir, int depth);
public:
- static std::vector GetTitleKeys(dvdcss_t drive);
+ static bool FindTitleKeys(dvdcss_t drive);
static uint32_t GetDistanceToNextFile(uint32_t currentSector);
static bool IsSectorInFile(uint32_t currentSector);
static sectorInfo* GetSectorInfo(uint32_t currentSector);
diff --git a/DumpDVD/Gui/DumpDVD.cpp b/DumpDVD/Gui/DumpDVD.cpp
index fd7154c..99f25f0 100644
--- a/DumpDVD/Gui/DumpDVD.cpp
+++ b/DumpDVD/Gui/DumpDVD.cpp
@@ -1,14 +1,7 @@
#include "DumpDVD.hpp"
#include
#include
-
-#ifdef _WIN32
-#include
-#include
-#endif
-
#include
-
#include
#include
#include
@@ -63,6 +56,10 @@ namespace Li::Gui {
this->lock->lock();
this->freeOldDriveList();
this->drivesList = pollDrives;
+
+ if (this->selectedDrive >= this->drivesList->size())
+ this->reset();
+
this->lock->unlock();
}
@@ -84,21 +81,17 @@ namespace Li::Gui {
}
void DumpDVD::reset() {
- if (this->GetCurrentSelectedDrive()->DiscInDrive())
+ if (this->GetCurrentSelectedDrive()->DiscInDrive()) {
this->selectedDriveSpeed = this->GetCurrentSelectedDrive()->SupportedSpeeds()->size();
- else
+ if (this->GetCurrentSelectedDrive()->HasCss()) {
+ this->decrypt = true;
+ }
+ }
+ else {
this->selectedDriveSpeed = 0;
+ }
- std::string documentsFolder = "";
-
-#ifdef _WIN32
- WCHAR documents[MAX_PATH];
- HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documents);
- std::wstring wDocuments = std::wstring(documents);
- documentsFolder = std::string(wDocuments.begin(), wDocuments.end());
-#endif
-
- std::filesystem::path p = std::filesystem::path(documentsFolder);
+ std::filesystem::path p = std::filesystem::path(Utils::GetDocumentsFolder());
p = p.append(GetCurrentSelectedDrive()->VolumeName()).replace_extension(".iso");
strncpy(this->outputFile, p.string().c_str(), sizeof(DumpDVD::outputFile)-1);
}
@@ -120,7 +113,7 @@ namespace Li::Gui {
}
this->dvdRipper = new Li::Dvd::DvdRipper(this->GetCurrentSelectedDrive(), std::string(this->outputFile), this->sectorsAtOnce);
- this->dvdRipper->StartRip(speed);
+ this->dvdRipper->StartRip(speed, this->decrypt);
this->imRippinIt = true;
}
@@ -147,24 +140,32 @@ namespace Li::Gui {
ImGui::ProgressBar(this->dvdRipper->PercentDone());
ImGui::Text("Sector %i / %i", this->dvdRipper->SectorsReadSoFar(), this->GetCurrentSelectedDrive()->Sectors());
- ImGui::Text("File: %i / %i", this->dvdRipper->FileSoFar(), this->dvdRipper->FileLen());
-
uint64_t szSoFar = (uint64_t)(this->dvdRipper->SectorsReadSoFar()) * (uint64_t)(DVDCSS_BLOCK_SIZE);
uint64_t szTotal = (uint64_t)(this->GetCurrentSelectedDrive()->Sectors()) * (uint64_t)(DVDCSS_BLOCK_SIZE);
ImGui::Text("Total %s / %s", Utils::HumanReadableByteStr(szSoFar).c_str(), Utils::HumanReadableByteStr(szTotal).c_str());
- ImGui::SeparatorText("Content Scrambling System (CSS)");
+ ImGui::SeparatorText("Copy Protection");
- std::byte* discKey = this->dvdRipper->GetDiscKey();
- std::byte* titleKey = this->dvdRipper->GetTitleKey();
- if (discKey != nullptr)
- ImGui::Text("Disc Key: %02X%02X%02X%02X%02X", discKey[0], discKey[1], discKey[2], discKey[3], discKey[4]);
- if (titleKey != nullptr)
- ImGui::Text("Title Key: %02X%02X%02X%02X%02X", titleKey[0], titleKey[1], titleKey[2], titleKey[3], titleKey[4]);
+ if (this->GetCurrentSelectedDrive()->HasCss()) {
+ ImGui::Text("Copy Protection: \"Content Scrambling System\" (CSS)");
+ ImGui::Text("Decrypt Enabled? %s", this->decrypt ? "Yes" : "No");
-
+ if (this->decrypt) {
+ std::byte* discKey = this->dvdRipper->GetDiscKey();
+ std::byte* titleKey = this->dvdRipper->GetTitleKey();
+
+ if (discKey != nullptr)
+ ImGui::Text("Disc Key: %02X%02X%02X%02X%02X", discKey[0], discKey[1], discKey[2], discKey[3], discKey[4]);
+
+ if (titleKey != nullptr)
+ ImGui::Text("Title Key: %02X%02X%02X%02X%02X", titleKey[0], titleKey[1], titleKey[2], titleKey[3], titleKey[4]);
+ }
+ }
+ else {
+ ImGui::Text("Copy Protection: None Detected.");
+ }
ImGui::SeparatorText("Output");
ImGui::Text("Output file: \"%s\"", this->outputFile);
@@ -209,7 +210,6 @@ namespace Li::Gui {
this->reset();
}
-
if (!GetCurrentSelectedDrive()->DiscInDrive()) {
ImGui::Text("Put a disc in the drive to continue ...");
this->discInserted = false;
@@ -248,6 +248,15 @@ namespace Li::Gui {
ImGui::InputInt("##bufferSize", &this->sectorsAtOnce, 1, 100);
if (this->sectorsAtOnce <= 0) this->sectorsAtOnce = 1;
+ ImGui::SeparatorText("Copy Protection");
+ if (this->GetCurrentSelectedDrive()->HasCss()) {
+ ImGui::Text("Copy Protection: \"Content Scrambling System\" (CSS)");
+ ImGui::Checkbox("Decrypt/Remove CSS", &this->decrypt);
+ }
+ else {
+ ImGui::Text("Copy Protection: None Detected.\n(This doesn't completely confirm there isn't any ...)");
+ }
+
ImGui::SeparatorText("Output");
ImGui::Text("Output file: ");
diff --git a/DumpDVD/Gui/DumpDVD.hpp b/DumpDVD/Gui/DumpDVD.hpp
index 9c21ffe..a92e6ba 100644
--- a/DumpDVD/Gui/DumpDVD.hpp
+++ b/DumpDVD/Gui/DumpDVD.hpp
@@ -20,6 +20,7 @@ namespace Li::Gui {
std::mutex* lock;
int sectorsAtOnce;
+ bool decrypt;
bool discInserted;
int selectedDrive;
int selectedDriveSpeed;
diff --git a/DumpDVD/Gui/SDL.cpp b/DumpDVD/Gui/SDL.cpp
index 1ca386f..9fda9b0 100644
--- a/DumpDVD/Gui/SDL.cpp
+++ b/DumpDVD/Gui/SDL.cpp
@@ -1,9 +1,12 @@
#include "SDL.hpp"
+
#ifdef _WIN32
#include "D3D.hpp"
#include
#include
#endif
+
+#include
#include
#include
@@ -14,7 +17,7 @@ namespace Li::Gui {
SDL::SDL(std::string windowTitle, int windowWidth, int windowHeight) {
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{
- std::cout << "Error: " << SDL_GetError() << std::endl;
+ std::cerr << "Error: " << SDL_GetError() << std::endl;
return;
}
@@ -29,6 +32,8 @@ namespace Li::Gui {
#ifdef _WIN32
HWND hwnd = (HWND)this->wmInfo.info.win.window;
this->renderer = new D3D(hwnd);
+#else
+#error no renderer for this platform
#endif
IMGUI_CHECKVERSION();
@@ -42,6 +47,8 @@ namespace Li::Gui {
#ifdef _WIN32
ImGui_ImplSDL2_InitForD3D(this->window);
this->renderer->InitImgui();
+#else
+#error No imgui renderer backend provided for this platform
#endif
isExiting = false;
}
@@ -63,6 +70,8 @@ namespace Li::Gui {
#ifdef _WIN32
D3D* d3d = (D3D*)this->renderer;
d3d->Resize();
+#else
+#error No resize method provided for this platform
#endif
}
}
diff --git a/DumpDVD/Scsi/IoCtl.cpp b/DumpDVD/Scsi/IoCtl.cpp
index 62894aa..9f0d65e 100644
--- a/DumpDVD/Scsi/IoCtl.cpp
+++ b/DumpDVD/Scsi/IoCtl.cpp
@@ -83,6 +83,9 @@ namespace Li::Scsi {
}
delete buffer;
+
+#else
+#error no way to get all supported read speeds on this platform
#endif
return speeds;
}
@@ -98,6 +101,8 @@ namespace Li::Scsi {
std::cerr << "Error getting geometry: " << std::to_string(GetLastError()) << std::endl;
}
return (uint64_t)(geometry.DiskSize.QuadPart / DVDCSS_BLOCK_SIZE);
+#else
+#error no way to get total sector count of disc on this platform ..
#endif
}
bool IoCtl::AllowReadingPastDisc() {
@@ -110,6 +115,8 @@ namespace Li::Scsi {
std::cerr << "Error enabling DASD I/O: " << std::to_string(GetLastError()) << std::endl;
}
return success;
+#else
+#error no way to disable bounds checks (DASHD) i/o on this platform (maybe not required?)
#endif
}
@@ -121,6 +128,8 @@ namespace Li::Scsi {
std::cerr << "Error unmounting drive: " << std::to_string(GetLastError()) << std::endl;
}
return success;
+#else
+#error no way to unmount drive on this platform
#endif
}
@@ -132,6 +141,8 @@ namespace Li::Scsi {
std::cerr << "Error mounting drive: " << std::to_string(GetLastError()) << std::endl;
}
return success;
+#else
+#error no way to mount drive on this platform
#endif
}
@@ -154,6 +165,8 @@ namespace Li::Scsi {
std::cerr << "Error Locking the drive: " << std::to_string(GetLastError()) << std::endl;
}
return success;
+#else
+#error no way to exclusive lock drive on this platform.
#endif
}
@@ -171,6 +184,8 @@ namespace Li::Scsi {
this->MountVolume();
return success;
+#else
+#error no way to exclusive unlock drive on this platform.
#endif
}
@@ -191,6 +206,8 @@ namespace Li::Scsi {
std::cerr << "Error setting speed: " << std::to_string(GetLastError()) << std::endl;
}
return success;
+#else
+#error no way to set drive speed folder on this platform.
#endif
}
diff --git a/DumpDVD/Scsi/OpticalDrive.cpp b/DumpDVD/Scsi/OpticalDrive.cpp
index 480ede1..dd9e9fc 100644
--- a/DumpDVD/Scsi/OpticalDrive.cpp
+++ b/DumpDVD/Scsi/OpticalDrive.cpp
@@ -1,5 +1,6 @@
#include "OpticalDrive.hpp"
#include "IoCtl.hpp"
+#include "SDL.h"
#ifdef _WIN32
#include
@@ -30,6 +31,8 @@ namespace Li::Scsi {
}
delete wChrVolumeName;
+#else
+#error no way to get optical drive information on this platform
#endif
}
@@ -40,6 +43,15 @@ namespace Li::Scsi {
IoCtl* ctl = new IoCtl(this->drivePath);
this->supportedSpeeds = ctl->GetSupportedReadSpeeds();
this->sectors = ctl->GetTotalSectors();
+
+ this->hasCss = dvdcss_is_scrambled(ctl->GetDvdCssHandle());
+ if (this->hasCss) {
+ this->discKey = (std::byte*)dvdcss_get_cur_disckey(ctl->GetDvdCssHandle());
+ }
+ else {
+ this->discKey = nullptr;
+ }
+
delete ctl;
}
}
@@ -60,6 +72,14 @@ namespace Li::Scsi {
return this->drivePath;
}
+ bool OpticalDrive::HasCss() {
+ return this->hasCss;
+ }
+
+ std::byte* OpticalDrive::DiscKey() {
+ return this->discKey;
+ }
+
uint32_t OpticalDrive::Sectors() {
return this->sectors;
}
@@ -88,6 +108,20 @@ namespace Li::Scsi {
}
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;
}
diff --git a/DumpDVD/Scsi/OpticalDrive.hpp b/DumpDVD/Scsi/OpticalDrive.hpp
index 510aa43..ab50f4b 100644
--- a/DumpDVD/Scsi/OpticalDrive.hpp
+++ b/DumpDVD/Scsi/OpticalDrive.hpp
@@ -8,6 +8,9 @@ namespace Li::Scsi {
std::string drivePath;
std::string volumeName;
+ bool hasCss;
+ std::byte* discKey;
+
bool discInDrive;
std::vector* supportedSpeeds;
uint32_t sectors;
@@ -21,6 +24,8 @@ namespace Li::Scsi {
std::string DrivePath();
std::string VolumeName();
uint32_t Sectors();
+ std::byte* DiscKey();
+ bool HasCss();
bool DiscInDrive();
static std::vector* ListOpticalDrives();
diff --git a/DumpDVD/Utils.cpp b/DumpDVD/Utils.cpp
index ff847de..0564f5d 100644
--- a/DumpDVD/Utils.cpp
+++ b/DumpDVD/Utils.cpp
@@ -2,7 +2,28 @@
#include
#include
+#ifdef _WIN32
+#include
+#include
+#endif
+
namespace Li {
+
+ std::string Utils::GetDocumentsFolder() {
+ std::string documentsFolder = "";
+
+#ifdef _WIN32
+ WCHAR documents[MAX_PATH];
+ HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documents);
+ std::wstring wDocuments = std::wstring(documents);
+ documentsFolder = std::string(wDocuments.begin(), wDocuments.end());
+#else
+#error no way to find documents folder on this platform.
+#endif
+
+ return documentsFolder;
+ }
+
bool Utils::CompareStringCaseInsensitive(std::string input, std::string compare) {
unsigned int sz = input.size();
if (compare.size() != sz)
diff --git a/DumpDVD/Utils.hpp b/DumpDVD/Utils.hpp
index 9bd6870..55f2fc1 100644
--- a/DumpDVD/Utils.hpp
+++ b/DumpDVD/Utils.hpp
@@ -3,6 +3,7 @@
namespace Li {
class Utils {
public:
+ static std::string GetDocumentsFolder();
static std::string HumanReadableByteStr(uint64_t bytes);
static bool CompareStringCaseInsensitive(std::string input, std::string compare);
};