Compare commits
2 Commits
f83e7addef
...
ed3801ab02
Author | SHA1 | Date |
---|---|---|
Li | ed3801ab02 | |
Li | ab8bd004fd |
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ namespace Li::Dvd {
|
|||
|
||||
static std::vector<sectorInfo*> 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<sectorInfo*> TitleKey::GetTitleKeys(dvdcss_t drive) {
|
||||
bool TitleKey::FindTitleKeys(dvdcss_t drive) {
|
||||
drv = drive;
|
||||
sectorsList = std::vector<sectorInfo*>();
|
||||
|
||||
|
@ -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() {
|
||||
|
|
|
@ -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<sectorInfo*> 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);
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
#include "DumpDVD.hpp"
|
||||
#include <imgui.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#include <portable-file-dialogs.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <filesystem>
|
||||
|
@ -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: ");
|
||||
|
@ -272,10 +281,11 @@ namespace Li::Gui {
|
|||
if (this->drivesList == nullptr) return;
|
||||
|
||||
const ImGuiViewport* mainViewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Appearing);
|
||||
ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize, ImGuiCond_Appearing);
|
||||
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize, ImGuiCond_Always);
|
||||
|
||||
ImGui::Begin("DVD Dumper", NULL, ImGuiWindowFlags_NoCollapse);
|
||||
ImGui::Begin("DVD Dumper", NULL, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoFocusOnAppearing);
|
||||
|
||||
if (this->imRippinIt)
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace Li::Gui {
|
|||
std::mutex* lock;
|
||||
|
||||
int sectorsAtOnce;
|
||||
bool decrypt;
|
||||
bool discInserted;
|
||||
int selectedDrive;
|
||||
int selectedDriveSpeed;
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
#include "SDL.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "D3D.hpp"
|
||||
#include <windows.h>
|
||||
#include <imgui_impl_dx11.h>
|
||||
#endif
|
||||
|
||||
#include <SDL.h>
|
||||
#include <imgui_impl_sdl2.h>
|
||||
#include <imgui.h>
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "OpticalDrive.hpp"
|
||||
#include "IoCtl.hpp"
|
||||
#include "SDL.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ namespace Li::Scsi {
|
|||
std::string drivePath;
|
||||
std::string volumeName;
|
||||
|
||||
bool hasCss;
|
||||
std::byte* discKey;
|
||||
|
||||
bool discInDrive;
|
||||
std::vector<uint32_t>* 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<OpticalDrive*>* ListOpticalDrives();
|
||||
|
|
|
@ -2,7 +2,28 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#include <shlobj.h>
|
||||
#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)
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue