#include "TitleKey.hpp" #include #include #include #include #include "../Utils.hpp" 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); 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(); 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(); } }