DumpDVD/DumpDVD/Dvd/TitleKey.cpp

112 lines
2.4 KiB
C++

#include "TitleKey.hpp"
#include <lib9660.h>
#include <iostream>
#include <vector>
#include <filesystem>
#include "../Utils.hpp"
namespace Li::Dvd {
static std::vector<sectorInfo*> sectorsList;
static dvdcss_t drv;
bool TitleKey::readSector(l9660_fs* fs, void* buf, uint32_t sector) {
dvdcss_seek(drv, sector, DVDCSS_SEEK_KEY);
dvdcss_read(drv, buf, 1, DVDCSS_READ_DECRYPT);
return !dvdcss_was_error(drv);
}
bool TitleKey::IsSectorInFile(uint32_t currentSector) {
for (sectorInfo* inf : sectorsList) {
if (currentSector >= inf->startSector && currentSector < inf->endSector)
return true;
}
return false;
}
uint32_t TitleKey::GetDistanceToNextFile(uint32_t currentSector) {
uint32_t lowestDistance = -1;
for (sectorInfo* inf : sectorsList) {
if (currentSector >= inf->startSector && currentSector < inf->endSector)
return 0;
uint32_t distance = inf->startSector - currentSector;
if (distance < 0) continue;
if (distance < lowestDistance) {
lowestDistance = distance;
}
}
return lowestDistance;
}
sectorInfo* TitleKey::GetSectorInfo(uint32_t currentSector) {
for (sectorInfo* inf : sectorsList) {
if (currentSector >= inf->startSector && currentSector < inf->endSector) {
return inf;
}
}
return nullptr;
}
void readDir(l9660_dir* dir) {
while (true) {
l9660_dirent* dent;
l9660_status status = l9660_readdir(dir, &dent);
if (dent == nullptr)
break;
if (dent->name_len < 2)
continue;
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) {
sectorInfo* file = new sectorInfo();
file->startSector = *(uint32_t*)dent->sector.le;
file->endSector = file->startSector + (*(uint32_t*)dent->size.le / DVDCSS_BLOCK_SIZE);
sectorsList.push_back(file);
}
}
}
std::vector<sectorInfo*> TitleKey::GetTitleKeys(dvdcss_t drive) {
drv = drive;
sectorsList = std::vector<sectorInfo*>();
l9660_dir rootDir;
l9660_fs isoFs;
l9660_status status;
status = l9660_openfs(&isoFs, TitleKey::readSector);
status = l9660_fs_open_root(&rootDir, &isoFs);
readDir(&rootDir);
return sectorsList;
}
void TitleKey::FreeMemory() {
for (sectorInfo* inf : sectorsList) {
delete inf;
}
sectorsList.clear();
}
}