add stuff
This commit is contained in:
parent
103bb58da3
commit
f83e7addef
|
@ -1,4 +1,5 @@
|
|||
#include "DvdRipper.hpp"
|
||||
#include <dvdcss.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
@ -15,16 +16,10 @@ namespace Li::Dvd {
|
|||
|
||||
|
||||
uint32_t DvdRipper::FileSoFar() {
|
||||
if (this->inFile)
|
||||
return this->fileReadSoFar;
|
||||
else
|
||||
return this->nonFileReadSoFar;
|
||||
return this->fileReadSoFar;
|
||||
}
|
||||
uint32_t DvdRipper::FileLen() {
|
||||
if (this->inFile)
|
||||
return this->fileRemain;
|
||||
else
|
||||
return this->nonFileRemain;
|
||||
return this->fileRemain;
|
||||
}
|
||||
|
||||
float DvdRipper::PercentDone() {
|
||||
|
@ -33,13 +28,18 @@ namespace Li::Dvd {
|
|||
uint32_t DvdRipper::SectorsReadSoFar() {
|
||||
return this->sectorsReadSoFar;
|
||||
}
|
||||
uint32_t DvdRipper::FileReadSoFar() {
|
||||
return this->fileReadSoFar;
|
||||
}
|
||||
std::string DvdRipper::OutputPath() {
|
||||
return this->outputPath;
|
||||
}
|
||||
|
||||
std::byte* DvdRipper::GetDiscKey() {
|
||||
return this->discKey;
|
||||
}
|
||||
|
||||
std::byte* DvdRipper::GetTitleKey() {
|
||||
return this->titleKey;
|
||||
}
|
||||
|
||||
bool DvdRipper::Done() {
|
||||
return this->done;
|
||||
}
|
||||
|
@ -49,102 +49,96 @@ namespace Li::Dvd {
|
|||
std::string DvdRipper::ErrorMessage() {
|
||||
return this->errorMsg;
|
||||
}
|
||||
int DvdRipper::read1SectorATimeSkippingBadSectors(int toRead) {
|
||||
memset(this->tmpBuffer, 0x00, this->sectorsAtOnce * DVDCSS_BLOCK_SIZE);
|
||||
int DvdRipper::read1SectorATimeSkippingBadSectors(int toRead) {
|
||||
int nmRd = 0;
|
||||
for (int i = 0; i < toRead; i++) {
|
||||
for (int retry = 0; retry < 10; retry++) {
|
||||
int dataRd = dvdcss_read(driveIoCtl->GetDvdCssHandle(), this->tmpBuffer + (i * DVDCSS_BLOCK_SIZE), 1, DVDCSS_READ_DECRYPT);
|
||||
memset(this->tmpBuffer, 0x00, DVDCSS_BLOCK_SIZE);
|
||||
int dataRd = dvdcss_read(driveIoCtl->GetDvdCssHandle(), this->tmpBuffer, 1, DVDCSS_READ_DECRYPT);
|
||||
if (dataRd < 0) {
|
||||
dvdcss_seek(driveIoCtl->GetDvdCssHandle(), this->sectorsReadSoFar, DVDCSS_SEEK_KEY);
|
||||
|
||||
if (retry+1 >= 10)
|
||||
dvdcss_seek(driveIoCtl->GetDvdCssHandle(), this->sectorsReadSoFar + 1, DVDCSS_SEEK_KEY);
|
||||
|
||||
continue; // retry
|
||||
}
|
||||
else {
|
||||
this->iso->write((const char*)this->tmpBuffer, DVDCSS_BLOCK_SIZE * dataRd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
nmRd += 1;
|
||||
this->sectorsReadSoFar += 1;
|
||||
this->fileReadSoFar += 1;
|
||||
|
||||
if (this->sectorsReadSoFar > this->drive->Sectors()) // check if we've read the last sector ...
|
||||
break;
|
||||
}
|
||||
|
||||
return nmRd;
|
||||
|
||||
}
|
||||
void DvdRipper::readNonFileSectors() {
|
||||
dvdcss_title(this->driveIoCtl->GetDvdCssHandle(), this->sectorsReadSoFar);
|
||||
|
||||
this->nonFileRemain = Li::Dvd::TitleKey::GetDistanceToNextFile(this->sectorsReadSoFar);
|
||||
if (this->nonFileRemain == (uint32_t)-1) {
|
||||
this->nonFileRemain = (this->drive->Sectors() - this->sectorsReadSoFar);
|
||||
}
|
||||
if ((this->sectorsReadSoFar + this->nonFileRemain) > this->drive->Sectors()) {
|
||||
this->nonFileRemain = (this->drive->Sectors() - this->sectorsReadSoFar);
|
||||
}
|
||||
this->nonFileReadSoFar = 0;
|
||||
|
||||
void DvdRipper::readSectors() {
|
||||
do {
|
||||
int toRead = this->sectorsAtOnce;
|
||||
if ((this->nonFileReadSoFar + toRead) > this->nonFileRemain) {
|
||||
toRead = this->nonFileRemain - this->nonFileReadSoFar;
|
||||
if ((this->fileReadSoFar + toRead) > this->fileRemain) {
|
||||
toRead = (this->fileRemain - this->fileReadSoFar);
|
||||
}
|
||||
|
||||
int numRead = dvdcss_read(driveIoCtl->GetDvdCssHandle(), this->tmpBuffer, toRead, DVDCSS_READ_DECRYPT);
|
||||
|
||||
if (dvdcss_was_error(driveIoCtl->GetDvdCssHandle())) {
|
||||
this->errorMsg = std::string(dvdcss_error(driveIoCtl->GetDvdCssHandle()));
|
||||
}
|
||||
if (numRead < 0) {
|
||||
dvdcss_seek(driveIoCtl->GetDvdCssHandle(), this->sectorsAtOnce, DVDCSS_SEEK_MPEG);
|
||||
numRead = read1SectorATimeSkippingBadSectors(toRead);
|
||||
dvdcss_seek(driveIoCtl->GetDvdCssHandle(), this->sectorsReadSoFar, DVDCSS_SEEK_KEY);
|
||||
read1SectorATimeSkippingBadSectors(toRead);
|
||||
}
|
||||
|
||||
this->iso->write((const char*)this->tmpBuffer, DVDCSS_BLOCK_SIZE * numRead);
|
||||
|
||||
this->sectorsReadSoFar += numRead;
|
||||
this->nonFileReadSoFar += numRead;
|
||||
|
||||
} while (this->nonFileReadSoFar < this->nonFileRemain && this->keepRunning);
|
||||
else {
|
||||
this->iso->write((const char*)this->tmpBuffer, DVDCSS_BLOCK_SIZE * numRead);
|
||||
this->sectorsReadSoFar += numRead;
|
||||
this->fileReadSoFar += numRead;
|
||||
}
|
||||
} while ( (this->fileReadSoFar < this->fileRemain) &&
|
||||
(this->sectorsReadSoFar < this->drive->Sectors()) &&
|
||||
this->keepRunning);
|
||||
|
||||
this->inFile = Li::Dvd::TitleKey::IsSectorInFile(this->sectorsReadSoFar);
|
||||
this->fileReadSoFar = 0;
|
||||
this->nonFileReadSoFar = 0;
|
||||
this->fileRemain = 0;
|
||||
}
|
||||
|
||||
void DvdRipper::readFileSectors() {
|
||||
void DvdRipper::readNonFileSectors() {
|
||||
dvdcss_title(this->driveIoCtl->GetDvdCssHandle(), this->sectorsReadSoFar);
|
||||
this->fileRemain = Li::Dvd::TitleKey::GetDistanceToNextFile(this->sectorsReadSoFar);
|
||||
|
||||
sectorInfo* sectorInf = Li::Dvd::TitleKey::GetSectorInfo(this->sectorsReadSoFar);
|
||||
this->fileRemain = (sectorInf->endSector - sectorInf->startSector);
|
||||
|
||||
if ((this->sectorsReadSoFar + this->fileRemain) > this->drive->Sectors()) {
|
||||
this->fileRemain = (this->drive->Sectors() - this->sectorsReadSoFar);
|
||||
}
|
||||
|
||||
this->fileReadSoFar = 0;
|
||||
|
||||
do {
|
||||
int toRead = this->sectorsAtOnce;
|
||||
if ((this->fileReadSoFar + toRead) > this->fileRemain) {
|
||||
toRead = this->fileRemain - this->fileReadSoFar;
|
||||
}
|
||||
int numRead = dvdcss_read(driveIoCtl->GetDvdCssHandle(), this->tmpBuffer, toRead, DVDCSS_READ_DECRYPT);
|
||||
|
||||
if (dvdcss_was_error(driveIoCtl->GetDvdCssHandle())) {
|
||||
this->errorMsg = std::string(dvdcss_error(driveIoCtl->GetDvdCssHandle()));
|
||||
}
|
||||
if (numRead <= 0) {
|
||||
numRead = read1SectorATimeSkippingBadSectors(toRead);
|
||||
}
|
||||
this->readSectors();
|
||||
}
|
||||
|
||||
iso->write((const char*)this->tmpBuffer, DVDCSS_BLOCK_SIZE * numRead);
|
||||
void DvdRipper::readFileSectors() {
|
||||
dvdcss_title(this->driveIoCtl->GetDvdCssHandle(), this->sectorsReadSoFar);
|
||||
this->titleKey = (std::byte*)dvdcss_get_cur_titlekey(this->driveIoCtl->GetDvdCssHandle());
|
||||
sectorInfo* sectorInf = Li::Dvd::TitleKey::GetSectorInfo(this->sectorsReadSoFar);
|
||||
this->fileRemain = (sectorInf->endSector - sectorInf->startSector);
|
||||
|
||||
this->sectorsReadSoFar += numRead;
|
||||
this->fileReadSoFar += numRead;
|
||||
if ((this->sectorsReadSoFar + this->fileRemain) > this->drive->Sectors()) {
|
||||
this->fileRemain = (this->drive->Sectors() - this->sectorsReadSoFar);
|
||||
}
|
||||
|
||||
} while ((this->fileReadSoFar < this->fileRemain) && this->keepRunning);
|
||||
|
||||
this->inFile = Li::Dvd::TitleKey::IsSectorInFile(this->sectorsReadSoFar);
|
||||
this->fileReadSoFar = 0;
|
||||
this->nonFileReadSoFar = 0;
|
||||
|
||||
this->readSectors();
|
||||
}
|
||||
|
||||
void DvdRipper::ripThread() {
|
||||
|
||||
|
||||
this->sectorsReadSoFar = 0;
|
||||
|
||||
Li::Dvd::TitleKey::GetTitleKeys(driveIoCtl->GetDvdCssHandle());
|
||||
|
@ -153,9 +147,9 @@ namespace Li::Dvd {
|
|||
|
||||
do {
|
||||
if (this->inFile)
|
||||
this->readFileSectors();
|
||||
this->readFileSectors(); // read & decrypt all files (including those associated w the filesystem)
|
||||
else
|
||||
this->readNonFileSectors();
|
||||
this->readNonFileSectors(); // read the data not associated with any file on the filesystem.
|
||||
|
||||
} while (this->sectorsReadSoFar < this->drive->Sectors() && this->keepRunning);
|
||||
|
||||
|
@ -172,9 +166,6 @@ namespace Li::Dvd {
|
|||
this->fileReadSoFar = 0;
|
||||
this->fileRemain = 0;
|
||||
|
||||
this->nonFileReadSoFar = 0;
|
||||
this->nonFileRemain = 0;
|
||||
|
||||
this->inFile = false;
|
||||
this->done = false;
|
||||
this->error = false;
|
||||
|
@ -182,7 +173,8 @@ namespace Li::Dvd {
|
|||
this->keepRunning = false;
|
||||
|
||||
this->ripinThread = nullptr;
|
||||
this->tmpBuffer = new uint8_t[DVDCSS_BLOCK_SIZE * this->sectorsAtOnce];
|
||||
this->tmpBuffer = new std::byte[DVDCSS_BLOCK_SIZE * this->sectorsAtOnce];
|
||||
|
||||
}
|
||||
|
||||
DvdRipper::~DvdRipper() {
|
||||
|
@ -204,6 +196,11 @@ namespace Li::Dvd {
|
|||
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->iso = new std::ofstream(this->outputPath, std::ios::binary);
|
||||
this->keepRunning = true;
|
||||
|
||||
|
|
|
@ -20,10 +20,6 @@ namespace Li::Dvd {
|
|||
uint32_t fileReadSoFar;
|
||||
uint32_t fileRemain;
|
||||
|
||||
uint32_t nonFileReadSoFar;
|
||||
uint32_t nonFileRemain;
|
||||
|
||||
|
||||
uint32_t sectorsAtOnce;
|
||||
uint32_t sectorsReadSoFar;
|
||||
|
||||
|
@ -33,26 +29,33 @@ namespace Li::Dvd {
|
|||
bool keepRunning;
|
||||
|
||||
std::ofstream* iso;
|
||||
uint8_t* tmpBuffer;
|
||||
|
||||
std::byte* tmpBuffer;
|
||||
|
||||
std::byte* titleKey;
|
||||
std::byte* discKey;
|
||||
|
||||
Li::Scsi::IoCtl* driveIoCtl;
|
||||
Li::Scsi::OpticalDrive* drive;
|
||||
void ripThread();
|
||||
void readNonFileSectors();
|
||||
void readFileSectors();
|
||||
|
||||
void readSectors();
|
||||
int read1SectorATimeSkippingBadSectors(int toRead);
|
||||
public:
|
||||
DvdRipper(Li::Scsi::OpticalDrive* opticalDrive, std::string outputISO, uint32_t sectorsAtOnce);
|
||||
~DvdRipper();
|
||||
|
||||
uint32_t SectorsReadSoFar();
|
||||
uint32_t FileReadSoFar();
|
||||
float PercentDone();
|
||||
std::string OutputPath();
|
||||
|
||||
uint32_t FileSoFar();
|
||||
uint32_t FileLen();
|
||||
|
||||
std::byte* GetTitleKey();
|
||||
std::byte* GetDiscKey();
|
||||
|
||||
bool Done();
|
||||
bool Error();
|
||||
std::string ErrorMessage();
|
||||
|
|
|
@ -29,12 +29,12 @@ namespace Li::Dvd {
|
|||
|
||||
uint32_t TitleKey::GetDistanceToNextFile(uint32_t currentSector) {
|
||||
|
||||
uint32_t lowestDistance = -1;
|
||||
uint32_t lowestDistance = 0xFFFFFFFF;
|
||||
for (sectorInfo* inf : sectorsList) {
|
||||
if (currentSector >= inf->startSector && currentSector < inf->endSector)
|
||||
return 0;
|
||||
|
||||
uint32_t distance = inf->startSector - currentSector;
|
||||
int32_t distance = (inf->startSector - currentSector);
|
||||
if (distance < 0) continue;
|
||||
|
||||
if (distance < lowestDistance) {
|
||||
|
@ -69,18 +69,34 @@ 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);
|
||||
}
|
||||
else if (TitleKey::GetSectorInfo(*(uint32_t*)dent->size.le) == nullptr) {
|
||||
else if (TitleKey::GetSectorInfo(cSector) == nullptr) {
|
||||
sectorInfo* file = new sectorInfo();
|
||||
file->startSector = cSector;
|
||||
|
||||
file->startSector = *(uint32_t*)dent->sector.le;
|
||||
file->endSector = file->startSector + (*(uint32_t*)dent->size.le / DVDCSS_BLOCK_SIZE);
|
||||
dvdcss_title(drv, file->startSector);
|
||||
char* titleKey = dvdcss_get_cur_titlekey(drv);
|
||||
|
||||
sectorsList.push_back(file);
|
||||
// check title is encrypted ...
|
||||
if (memcmp(titleKey, "\0\0\0\0\0", 5)) {
|
||||
// Round to sector boundary
|
||||
uint32_t sz = (*(uint32_t*)dent->size.le);
|
||||
if((sz % DVDCSS_BLOCK_SIZE) != 0)
|
||||
sz += (DVDCSS_BLOCK_SIZE - (sz % DVDCSS_BLOCK_SIZE));
|
||||
file->endSector = (file->startSector + (sz / DVDCSS_BLOCK_SIZE));
|
||||
|
||||
sectorsList.push_back(file);
|
||||
}
|
||||
else {
|
||||
delete file;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -147,12 +147,24 @@ 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->FileReadSoFar(), this->dvdRipper->FileLen());
|
||||
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)");
|
||||
|
||||
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]);
|
||||
|
||||
|
||||
ImGui::SeparatorText("Output");
|
||||
ImGui::Text("Output file: \"%s\"", this->outputFile);
|
||||
|
||||
|
|
Binary file not shown.
|
@ -106,6 +106,8 @@ LIBDVDCSS_EXPORT const char *dvdcss_error ( const dvdcss_t );
|
|||
|
||||
LIBDVDCSS_EXPORT int dvdcss_is_scrambled ( dvdcss_t );
|
||||
|
||||
LIBDVDCSS_EXPORT char* dvdcss_get_cur_disckey(dvdcss_t dvdcss);
|
||||
LIBDVDCSS_EXPORT char* dvdcss_get_cur_titlekey(dvdcss_t dvdcss);
|
||||
LIBDVDCSS_EXPORT int dvdcss_title(dvdcss_t dvdcss, int i_block);
|
||||
LIBDVDCSS_EXPORT int dvdcss_get_raw_fd(dvdcss_t);
|
||||
LIBDVDCSS_EXPORT int dvdcss_was_error(dvdcss_t);
|
||||
|
|
|
@ -486,7 +486,16 @@ static void init_cache( dvdcss_t dvdcss )
|
|||
/* If the cache is enabled, create a DVD-specific subdirectory. */
|
||||
create_cache_subdir( dvdcss );
|
||||
}
|
||||
int dvdcss_was_error_common(dvdcss_t drive) {
|
||||
|
||||
LIBDVDCSS_EXPORT char* dvdcss_get_cur_disckey(dvdcss_t dvdcss) {
|
||||
return dvdcss->css.p_disc_key;
|
||||
}
|
||||
LIBDVDCSS_EXPORT char* dvdcss_get_cur_titlekey(dvdcss_t dvdcss) {
|
||||
return dvdcss->css.p_title_key;
|
||||
}
|
||||
|
||||
LIBDVDCSS_EXPORT int dvdcss_was_error(dvdcss_t drive)
|
||||
{
|
||||
if (drive->b_errors)
|
||||
{
|
||||
drive->b_errors = FALSE;
|
||||
|
@ -495,18 +504,9 @@ int dvdcss_was_error_common(dvdcss_t drive) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
int dvdcss_get_fd_common(dvdcss_t drive) {
|
||||
return drive->i_fd;
|
||||
}
|
||||
|
||||
LIBDVDCSS_EXPORT int dvdcss_was_error(dvdcss_t drive)
|
||||
{
|
||||
return dvdcss_was_error_common(drive);
|
||||
}
|
||||
|
||||
LIBDVDCSS_EXPORT int dvdcss_get_raw_fd(dvdcss_t drive)
|
||||
{
|
||||
return dvdcss_get_fd_common(drive);
|
||||
return drive->i_fd;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue