DumpDVD/DumpDVD/Dvd/TitleKey.cpp

150 lines
3.3 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;
static int depth = 0;
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) {
uint64_t lowestDistance = 0xffffffffffffffff;
for (sectorInfo* inf : sectorsList) {
if (currentSector >= inf->startSector && currentSector < inf->endSector)
return 0;
int32_t distance = (inf->startSector - currentSector);
if (distance < 0) continue;
if (distance < lowestDistance) {
lowestDistance = distance;
}
}
if (lowestDistance == 0xffffffffffffffff)
return 0;
return (uint32_t)lowestDistance;
}
sectorInfo* TitleKey::GetSectorInfo(uint32_t currentSector) {
for (sectorInfo* inf : sectorsList) {
if (currentSector >= inf->startSector && currentSector < inf->endSector) {
return inf;
}
}
return nullptr;
}
sectorInfo* TitleKey::getFile(uint32_t start, uint32_t sz) {
sectorInfo* file = new sectorInfo();
file->startSector = start;
if ((sz % DVDCSS_BLOCK_SIZE) != 0) {
sz += (DVDCSS_BLOCK_SIZE - (sz % DVDCSS_BLOCK_SIZE));
}
file->endSector = (file->startSector + (sz / DVDCSS_BLOCK_SIZE));
return file;
}
void TitleKey::addFileIfExist(sectorInfo* file) {
dvdcss_title(drv, file->startSector);
char* titleKey = dvdcss_get_cur_titlekey(drv);
// check title is encrypted ...
if (memcmp(titleKey, "\0\0\0\0\0", 5) && GetSectorInfo(file->startSector) == nullptr) {
sectorsList.push_back(file);
}
else {
delete file;
}
}
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;
if (l9660_readdir(dir, &dent) != L9660_OK) return false;
if (dent == nullptr)
break;
if (dent->name_len < 2)
continue;
if ((dent->flags & DENT_ISDIR) != 0) {
l9660_dir ndir;
if (l9660_opendirat(&ndir, dir, dent->name) != L9660_OK) return false;
success = readDir(&ndir, depth + 1);
}
else {
addFileIfExist(getFile(*(uint32_t*)dent->sector.le, *(uint32_t*)dent->size.le));
addFileIfExist(getFile(_byteswap_ulong(*(uint32_t*)dent->sector.be), _byteswap_ulong(*(uint32_t*)dent->size.be)));
}
}
return success;
}
bool TitleKey::FindTitleKeys(dvdcss_t drive) {
drv = drive;
sectorsList = std::vector<sectorInfo*>();
l9660_dir rootDir;
l9660_fs isoFs;
l9660_status status;
if (l9660_openfs(&isoFs, TitleKey::readSector) == L9660_OK) {
if (l9660_fs_open_root(&rootDir, &isoFs) == L9660_OK) {
return TitleKey::readDir(&rootDir);
}
}
return false;
}
void TitleKey::FreeMemory() {
for (sectorInfo* inf : sectorsList) {
delete inf;
}
sectorsList.clear();
}
}