From 84f2ec35ccb32dfee05ad57f13fb0367bfdcacfc Mon Sep 17 00:00:00 2001 From: Li Date: Tue, 21 Mar 2023 23:12:28 +1300 Subject: [PATCH] Fix some bugz --- DumpDVD.sln | 4 +- DumpDVD/Dvd/DvdRipper.cpp | 45 ++++++--- DumpDVD/Dvd/DvdRipper.hpp | 16 +++- DumpDVD/Gui/D3D.cpp | 4 +- DumpDVD/Gui/DumpDVD.cpp | 166 ++++++++++++++++++++-------------- DumpDVD/Gui/DumpDVD.hpp | 2 +- DumpDVD/Gui/SDL.cpp | 3 +- DumpDVD/Main.cpp | 55 ----------- DumpDVD/Scsi/IoCtl.cpp | 30 +++--- DumpDVD/Scsi/IoCtl.hpp | 4 +- DumpDVD/Scsi/OpticalDrive.cpp | 27 +++--- DumpDVD/Scsi/OpticalDrive.hpp | 2 +- DumpDVD/Utils.cpp | 8 ++ DumpDVD/Utils.hpp | 1 + lib/libdvdcss.lib | Bin 270436 -> 272142 bytes libdvdcss/src/device.c | 14 ++- libdvdcss/src/ioctl.c | 26 ++++++ libdvdcss/src/ioctl.h | 3 +- 18 files changed, 231 insertions(+), 179 deletions(-) diff --git a/DumpDVD.sln b/DumpDVD.sln index 62d0753..fd6442d 100644 --- a/DumpDVD.sln +++ b/DumpDVD.sln @@ -34,8 +34,8 @@ Global {A9A5F041-541F-47EA-B583-DE84B59D9B62}.Release|x86.Build.0 = Release|Win32 {50F2BF62-8520-4B37-97DD-578EA282EC04}.Debug|x64.ActiveCfg = Debug|x64 {50F2BF62-8520-4B37-97DD-578EA282EC04}.Debug|x64.Build.0 = Debug|x64 - {50F2BF62-8520-4B37-97DD-578EA282EC04}.Debug|x86.ActiveCfg = Release|Win32 - {50F2BF62-8520-4B37-97DD-578EA282EC04}.Debug|x86.Build.0 = Release|Win32 + {50F2BF62-8520-4B37-97DD-578EA282EC04}.Debug|x86.ActiveCfg = Debug|Win32 + {50F2BF62-8520-4B37-97DD-578EA282EC04}.Debug|x86.Build.0 = Debug|Win32 {50F2BF62-8520-4B37-97DD-578EA282EC04}.Release|x64.ActiveCfg = Release|x64 {50F2BF62-8520-4B37-97DD-578EA282EC04}.Release|x64.Build.0 = Release|x64 {50F2BF62-8520-4B37-97DD-578EA282EC04}.Release|x86.ActiveCfg = Release|Win32 diff --git a/DumpDVD/Dvd/DvdRipper.cpp b/DumpDVD/Dvd/DvdRipper.cpp index 73aaef8..f117de1 100644 --- a/DumpDVD/Dvd/DvdRipper.cpp +++ b/DumpDVD/Dvd/DvdRipper.cpp @@ -13,7 +13,13 @@ namespace Li::Dvd { + uint32_t DvdRipper::FailedReads() { + return this->failedReads; + } + uint32_t DvdRipper::RetriedReads() { + return this->retriedReads; + } uint32_t DvdRipper::FileSoFar() { return this->fileReadSoFar; @@ -44,6 +50,10 @@ namespace Li::Dvd { return this->decrypt; } + bool DvdRipper::Starting() { + return this->starting; + } + bool DvdRipper::Done() { return this->done; } @@ -55,16 +65,20 @@ namespace Li::Dvd { } int DvdRipper::read1SectorATimeSkippingBadSectors(int toRead) { int nmRd = 0; + int numRetry = 5; for (int i = 0; i < toRead; i++) { - for (int retry = 0; retry < 10; retry++) { + for (int retry = 0; retry < numRetry; retry++) { memset(this->tmpBuffer, 0x00, DVDCSS_BLOCK_SIZE); 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, (this->decrypt ? DVDCSS_SEEK_KEY : DVDCSS_NOFLAGS) ); - if (retry+1 >= 10) + if ((retry + 1) >= numRetry) { dvdcss_seek(driveIoCtl->GetDvdCssHandle(), this->sectorsReadSoFar + 1, (this->decrypt ? DVDCSS_SEEK_KEY : DVDCSS_NOFLAGS)); + this->failedReads++; + } + this->retriedReads++; continue; // retry } else { @@ -173,13 +187,17 @@ namespace Li::Dvd { // 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); + + dvdcss_title(this->driveIoCtl->GetDvdCssHandle(), 0); + this->titleKey = (std::byte*)dvdcss_get_cur_titlekey(this->driveIoCtl->GetDvdCssHandle()); } + this->starting = false; + do { if (this->decrypt) { if (this->inFile) { @@ -207,8 +225,10 @@ namespace Li::Dvd { this->outputPath = outputISO; this->sectorsAtOnce = sectorsAtOnce; + this->failedReads = 0; + this->retriedReads = 0; + this->sectorsReadSoFar = 0; - this->fileReadSoFar = 0; this->fileRemain = 0; @@ -217,6 +237,7 @@ namespace Li::Dvd { this->error = false; this->errorMsg = ""; this->keepRunning = false; + this->starting = false; this->ripinThread = nullptr; this->tmpBuffer = new std::byte[DVDCSS_BLOCK_SIZE * this->sectorsAtOnce]; @@ -241,21 +262,17 @@ namespace Li::Dvd { this->driveIoCtl = new Li::Scsi::IoCtl(this->drive->DrivePath()); this->driveIoCtl->AllowReadingPastDisc(); this->driveIoCtl->SetDriveSpeed(driveSpeed, driveSpeed); - this->driveIoCtl->ExclusiveLockDrive(); 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->starting = true; this->iso = new std::ofstream(this->outputPath, std::ios::binary); this->keepRunning = true; + //this->driveIoCtl->ExclusiveLockDrive(); this->ripinThread = new std::thread(&DvdRipper::ripThread, this); } @@ -268,15 +285,15 @@ namespace Li::Dvd { this->sectorsReadSoFar = 0; this->fileReadSoFar = 0; this->keepRunning = false; - this->ripinThread->detach(); - + this->ripinThread->join(); + delete this->driveIoCtl; delete this->ripinThread; + this->ripinThread = nullptr; iso->close(); delete iso; this->iso = nullptr; - this->driveIoCtl->ExclusiveUnlockDrive(); } } \ No newline at end of file diff --git a/DumpDVD/Dvd/DvdRipper.hpp b/DumpDVD/Dvd/DvdRipper.hpp index 1abda7e..5c6c8ca 100644 --- a/DumpDVD/Dvd/DvdRipper.hpp +++ b/DumpDVD/Dvd/DvdRipper.hpp @@ -12,23 +12,29 @@ namespace Li::Dvd { class DvdRipper { private: + uint32_t retriedReads; + uint32_t failedReads; + bool error; bool done; + + bool keepRunning; + bool starting; + bool decrypt; + std::string errorMsg; bool inFile; uint32_t fileReadSoFar; uint32_t fileRemain; + uint32_t sectorsAtOnce; uint32_t sectorsReadSoFar; std::string outputPath; std::thread* ripinThread; - bool keepRunning; - bool decrypt; - std::ofstream* iso; std::byte* tmpBuffer; @@ -55,10 +61,14 @@ namespace Li::Dvd { uint32_t FileSoFar(); uint32_t FileLen(); + uint32_t FailedReads(); + uint32_t RetriedReads(); + bool Decrypt(); std::byte* GetTitleKey(); std::byte* GetDiscKey(); + bool Starting(); bool Done(); bool Error(); std::string ErrorMessage(); diff --git a/DumpDVD/Gui/D3D.cpp b/DumpDVD/Gui/D3D.cpp index f3ec50c..6165853 100644 --- a/DumpDVD/Gui/D3D.cpp +++ b/DumpDVD/Gui/D3D.cpp @@ -1,4 +1,6 @@ #include "D3D.hpp" +#include "../Utils.hpp" + #include #include #include @@ -115,7 +117,7 @@ namespace Li::Gui { if (errorObj) { std::string error = std::string((const char*)(errorObj->GetBufferPointer())); - std::cerr << error << std::endl; + Utils::ShowErrorMessage("Failed to compile shader: " + error); errorObj->Release(); } return res; diff --git a/DumpDVD/Gui/DumpDVD.cpp b/DumpDVD/Gui/DumpDVD.cpp index 66e97ad..5c3cedd 100644 --- a/DumpDVD/Gui/DumpDVD.cpp +++ b/DumpDVD/Gui/DumpDVD.cpp @@ -52,7 +52,7 @@ namespace Li::Gui { void DumpDVD::pollDrivesThread() { while (this->keepPolling) { this->refreshDriveList(); - std::this_thread::sleep_for(std::chrono::seconds(10)); + std::this_thread::sleep_for(std::chrono::seconds(5)); } } @@ -140,21 +140,31 @@ namespace Li::Gui { this->pollDrives = new std::thread(&DumpDVD::pollDrivesThread, this); } - + void DumpDVD::showStarting() { + ImGui::SeparatorText("Status"); + ImGui::Text("Starting copy..."); + } void DumpDVD::showRippingStatus() { ImGui::SeparatorText("Status"); + ImGui::Text("Copying Disc ... "); ImGui::SameLine(); ImGui::ProgressBar(this->dvdRipper->PercentDone()); - ImGui::Text("Sector %i / %i", this->dvdRipper->SectorsReadSoFar(), this->GetCurrentSelectedDrive()->Sectors()); + ImGui::Text("Sector %i / %i", this->dvdRipper->SectorsReadSoFar(), this->GetCurrentSelectedDrive()->Sectors()); 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()); - + + if (this->dvdRipper->FailedReads() > 0) { + ImGui::SeparatorText("Errors"); + ImGui::Text("Retried: %i", this->dvdRipper->RetriedReads()); + ImGui::Text("Failed: %i", this->dvdRipper->FailedReads()); + } + ImGui::SeparatorText("Copy Protection"); if (this->GetCurrentSelectedDrive()->HasCss()) { @@ -164,10 +174,10 @@ namespace Li::Gui { 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]); } @@ -194,9 +204,13 @@ namespace Li::Gui { ImGui::End(); } else { - ImGui::Begin("Error", &this->imRippinIt, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize); - ImGui::Text("Error occured when creating an ISO\n\"%s\"", this->dvdRipper->ErrorMessage().c_str()); - if (ImGui::Button("OK")) { + ImGui::Begin("Completed with Error", &this->imRippinIt, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize); + ImGui::Text("ISO file was created with errors ...\n\"%s\"\nDo you want to keep the ISO File?", this->dvdRipper->ErrorMessage().c_str()); + if (ImGui::Button("Keep")) { + this->endRipAndGoBackToMenu(); + } + ImGui::SameLine(); + if(ImGui::Button("Remove")) { this->endRipAndGoBackToMenu(); std::filesystem::remove(std::string(this->outputFile)); } @@ -212,77 +226,86 @@ namespace Li::Gui { ImGui::SeparatorText("Input"); - ImGui::Text("Drive: "); - ImGui::SameLine(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (ImGui::Combo("##driveList", &this->selectedDrive, this->getDrivesStr().c_str())) { - this->reset(); - } - - if (!GetCurrentSelectedDrive()->DiscInDrive()) { - ImGui::Text("Put a disc in the drive to continue ..."); - this->discInserted = false; + if (this->drivesList == nullptr || + this->drivesList->size() <= 0) { + ImGui::Text("No Optical Drives were found!"); + ImGui::Text("Please connect an CD, DVD or Blu Ray drive to this computer."); + ImGui::Text("\n"); + ImGui::Text("If you do have one connected, please make sure it is working properly"); + ImGui::Text("and that is not being used by another process."); } else { - if (!this->discInserted) { - this->discInserted = true; + ImGui::Text("Drive: "); + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (ImGui::Combo("##driveList", &this->selectedDrive, this->getDrivesStr().c_str())) { this->reset(); } - int numDrvSpeeds = GetCurrentSelectedDrive()->SupportedSpeeds()->size() + 1; - std::string driveSpeedName = "Unknown"; - if (this->selectedDriveSpeed >= 0 && this->selectedDriveSpeed < GetCurrentSelectedDrive()->SupportedSpeeds()->size()) { - uint32_t speed = GetCurrentSelectedDrive()->SupportedSpeeds()->at(this->selectedDriveSpeed); - float spdFriendly = ((float)speed / (float)1352.0); - - std::ostringstream xAmt; - xAmt.precision(1); - xAmt << std::fixed << spdFriendly; - - driveSpeedName = xAmt.str() + "x (" + std::to_string(speed) + " kbps)"; - } - else if (this->selectedDriveSpeed == GetCurrentSelectedDrive()->SupportedSpeeds()->size()) { - driveSpeedName = "As Fast as Possible"; - } - - - ImGui::Text("Read Speed: "); - ImGui::SameLine(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - ImGui::SliderInt("##readSpeed", &this->selectedDriveSpeed, 0, numDrvSpeeds - 1, driveSpeedName.c_str()); - - ImGui::Text("Buffer Size (in sectors): "); - ImGui::SameLine(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - 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); + if (!GetCurrentSelectedDrive()->DiscInDrive()) { + ImGui::Text("Put a disc in the drive to continue ..."); + this->discInserted = false; } else { - ImGui::Text("Copy Protection: None Detected.\n(This doesn't completely confirm there isn't any ...)"); - } + if (!this->discInserted) { + this->discInserted = true; + this->reset(); + } + int numDrvSpeeds = GetCurrentSelectedDrive()->SupportedSpeeds()->size() + 1; - ImGui::SeparatorText("Output"); + std::string driveSpeedName = "Unknown"; + if (this->selectedDriveSpeed >= 0 && this->selectedDriveSpeed < GetCurrentSelectedDrive()->SupportedSpeeds()->size()) { + uint32_t speed = GetCurrentSelectedDrive()->SupportedSpeeds()->at(this->selectedDriveSpeed); + float spdFriendly = ((float)speed / (float)1352.0); - ImGui::Text("Output file: "); - ImGui::SameLine(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 60); - ImGui::InputTextWithHint("##outputIso", "Output ISO file path", this->outputFile, IM_ARRAYSIZE(DumpDVD::outputFile)); - ImGui::SameLine(); - if (ImGui::Button("Browse")) { - auto sav = pfd::save_file("Save ISO", std::string(this->outputFile), { "ISO9660 Image Files (.iso)", "*.iso" }, pfd::opt::force_overwrite); - strncpy(this->outputFile, sav.result().c_str(), sizeof(DumpDVD::outputFile) - 1); - } + std::ostringstream xAmt; + xAmt.precision(1); + xAmt << std::fixed << spdFriendly; - if (ImGui::Button("Create ISO", ImVec2(ImGui::GetContentRegionAvail().x, 20))) { - this->startRip(); + driveSpeedName = xAmt.str() + "x (" + std::to_string(speed) + " kbps)"; + } + else if (this->selectedDriveSpeed == GetCurrentSelectedDrive()->SupportedSpeeds()->size()) { + driveSpeedName = "As Fast as Possible"; + } + + + ImGui::Text("Read Speed: "); + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + ImGui::SliderInt("##readSpeed", &this->selectedDriveSpeed, 0, numDrvSpeeds - 1, driveSpeedName.c_str()); + + ImGui::Text("Buffer Size (in sectors): "); + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + 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: "); + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 60); + ImGui::InputTextWithHint("##outputIso", "Output ISO file path", this->outputFile, IM_ARRAYSIZE(DumpDVD::outputFile)); + ImGui::SameLine(); + if (ImGui::Button("Browse")) { + auto sav = pfd::save_file("Save ISO", std::string(this->outputFile), { "ISO9660 Image Files (.iso)", "*.iso" }, pfd::opt::force_overwrite); + strncpy(this->outputFile, sav.result().c_str(), sizeof(DumpDVD::outputFile) - 1); + } + + if (ImGui::Button("Create ISO", ImVec2(ImGui::GetContentRegionAvail().x, 20))) { + this->startRip(); + } } } - this->lock->unlock(); } @@ -299,7 +322,12 @@ namespace Li::Gui { if (this->imRippinIt) { - this->showRippingStatus(); + if (this->dvdRipper->Starting()) { + this->showStarting(); + } + else { + this->showRippingStatus(); + } } else { diff --git a/DumpDVD/Gui/DumpDVD.hpp b/DumpDVD/Gui/DumpDVD.hpp index 2192a23..122a1de 100644 --- a/DumpDVD/Gui/DumpDVD.hpp +++ b/DumpDVD/Gui/DumpDVD.hpp @@ -31,7 +31,6 @@ namespace Li::Gui { Li::Dvd::DvdRipper* dvdRipper; - void ripDiscThread(); void pollDrivesThread(); void freeOldDriveList(); @@ -44,6 +43,7 @@ namespace Li::Gui { void endRipAndGoBackToMenu(); void showRipMenu(); + void showStarting(); void showRippingStatus(); public: diff --git a/DumpDVD/Gui/SDL.cpp b/DumpDVD/Gui/SDL.cpp index a977c4b..a3c01aa 100644 --- a/DumpDVD/Gui/SDL.cpp +++ b/DumpDVD/Gui/SDL.cpp @@ -1,4 +1,5 @@ #include "SDL.hpp" +#include "../Utils.hpp" #ifdef _WIN32 #include "D3D.hpp" @@ -22,7 +23,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::cerr << "Error: " << SDL_GetError() << std::endl; + Utils::ShowErrorMessage("Failed to initalize SDL: " + std::string(SDL_GetError())); return; } diff --git a/DumpDVD/Main.cpp b/DumpDVD/Main.cpp index 2243677..45a4852 100644 --- a/DumpDVD/Main.cpp +++ b/DumpDVD/Main.cpp @@ -4,63 +4,8 @@ #ifdef _WIN32 #include #endif -//#include "Extra.h" -//#include - -//const int readAtOnce = 0x1000; -//static uint8_t buffer[DVDCSS_BLOCK_SIZE * readAtOnce]; - int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { Li::Gui::MainWindow* mainWindow = new Li::Gui::MainWindow(); delete mainWindow; - - /*FILE* fd; - fopen_s(&fd, "out.iso", "wb"); - if (fd == NULL) return 1; - - dvdcss_t drive = dvdcss_open(argv[1]); - HANDLE handle = (HANDLE)dvdcss_get_raw_fd(drive); - - uint64_t totalSectors = getTotalSectors(handle); - allowReadPastDisc(handle); - setDriveSpeed(handle, 0xFFFF, 0xFFFF); - dvdcss_seek(drive, 0, DVDCSS_SEEK_KEY); - - time_t stime; - time(&stime); - - uint64_t currentSector = 0; - int sectorsRead = 0; - do { - int sectorsToRead = readAtOnce; - if ( (currentSector + sectorsToRead) > totalSectors) { - sectorsToRead = totalSectors - currentSector; - } - - sectorsRead = dvdcss_read(drive, buffer, sectorsToRead, DVDCSS_READ_DECRYPT); - - if (sectorsRead <= 0) { - printf("\nthere was an error; SectorsRead = %i\nLastError = %i\n", sectorsRead, GetLastError()); - break; - } - - fwrite(buffer, DVDCSS_BLOCK_SIZE * sectorsRead, 1, fd); - - currentSector += sectorsRead; - - float progress = (((float)currentSector / (float)totalSectors) * 100.0); - printf("ripping dvd: %llu/%llu %f%%\r", currentSector, totalSectors, progress); - } while (currentSector < totalSectors); - - time_t etime; - time(&etime); - - time_t difference = (etime - stime); - - printf("\nstart time: %llu \nend time: %llu \n\ntotal time taken: %llus\n", stime, etime, difference); - - fclose(fd); - - return 0;*/ } \ No newline at end of file diff --git a/DumpDVD/Scsi/IoCtl.cpp b/DumpDVD/Scsi/IoCtl.cpp index 9f0d65e..db6c28b 100644 --- a/DumpDVD/Scsi/IoCtl.cpp +++ b/DumpDVD/Scsi/IoCtl.cpp @@ -1,7 +1,7 @@ #include "IoCtl.hpp" +#include "../Utils.hpp" #ifdef _WIN32 - #define _NTSCSI_USER_MODE_ 1 #include #include @@ -12,9 +12,9 @@ #include #include #include - #endif + #include #include #include @@ -52,7 +52,8 @@ namespace Li::Scsi { DWORD unused; BOOL success = DeviceIoControl((HANDLE)this->osFileHandle, IOCTL_CDROM_GET_PERFORMANCE, &perfRequest, sizeof(CDROM_PERFORMANCE_REQUEST), perfHeader, sz, &unused, nullptr); if (!success) { - std::cerr << "Error getting supported read speeds: " << std::to_string(GetLastError()) << std::endl; + Utils::ShowErrorMessage("Error getting supported read speeds: " + std::to_string(GetLastError())); + return speeds; } uint64_t dataLen = _byteswap_ulong(*(uint32_t*)perfHeader->DataLength); @@ -98,7 +99,7 @@ namespace Li::Scsi { DWORD unused; BOOL success = DeviceIoControl((HANDLE)this->osFileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, nullptr, 0, &geometry, sizeof(DISK_GEOMETRY_EX), &unused, nullptr); if (!success) { - std::cerr << "Error getting geometry: " << std::to_string(GetLastError()) << std::endl; + Utils::ShowErrorMessage("Error getting geometry: " + std::to_string(GetLastError())); } return (uint64_t)(geometry.DiskSize.QuadPart / DVDCSS_BLOCK_SIZE); #else @@ -112,7 +113,7 @@ namespace Li::Scsi { DWORD unused; BOOL success = DeviceIoControl((HANDLE)this->osFileHandle, FSCTL_ALLOW_EXTENDED_DASD_IO, nullptr, 0, nullptr, 0, &unused, nullptr); if (!success) { - std::cerr << "Error enabling DASD I/O: " << std::to_string(GetLastError()) << std::endl; + Utils::ShowErrorMessage("Error enabling DASD I/O: " + std::to_string(GetLastError())); } return success; #else @@ -120,12 +121,12 @@ namespace Li::Scsi { #endif } - bool IoCtl::UnmountVolume() { + /*bool IoCtl::UnmountVolume() { #ifdef _WIN32 DWORD unused; BOOL success = DeviceIoControl((HANDLE)this->osFileHandle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &unused, nullptr); if (!success) { - std::cerr << "Error unmounting drive: " << std::to_string(GetLastError()) << std::endl; + Utils::ShowErrorMessage("Error unmounting drive: " + std::to_string(GetLastError())); } return success; #else @@ -138,7 +139,7 @@ namespace Li::Scsi { DWORD unused; BOOL success = DeviceIoControl((HANDLE)this->osFileHandle, FSCTL_UNLOCK_VOLUME, nullptr, 0, nullptr, 0, &unused, nullptr); if (!success) { - std::cerr << "Error mounting drive: " << std::to_string(GetLastError()) << std::endl; + Utils::ShowErrorMessage("Error mounting drive: " + std::to_string(GetLastError())); } return success; #else @@ -148,7 +149,6 @@ namespace Li::Scsi { bool IoCtl::ExclusiveLockDrive() { #ifdef _WIN32 - this->UnmountVolume(); DWORD unused; @@ -157,12 +157,13 @@ namespace Li::Scsi { exclusiveLockRequest.Access.RequestType = ExclusiveAccessLockDevice; exclusiveLockRequest.Access.Flags = CDROM_LOCK_IGNORE_VOLUME; + int err = GetLastError(); strncpy((char*)(exclusiveLockRequest.CallerName), "LiDeeVeeDeeDumperProgramThing", CDROM_EXCLUSIVE_CALLER_LENGTH - 1); BOOL success = DeviceIoControl((HANDLE)this->osFileHandle, IOCTL_CDROM_EXCLUSIVE_ACCESS, &exclusiveLockRequest, sizeof(CDROM_EXCLUSIVE_LOCK), nullptr, 0, &unused, nullptr); if (!success) { - std::cerr << "Error Locking the drive: " << std::to_string(GetLastError()) << std::endl; + //Utils::ShowErrorMessage("Error Locking the drive: " + std::to_string(GetLastError())); } return success; #else @@ -176,10 +177,11 @@ namespace Li::Scsi { CDROM_EXCLUSIVE_ACCESS exclusiveUnlockRequest; memset(&exclusiveUnlockRequest, 0x00, sizeof(CDROM_EXCLUSIVE_ACCESS)); exclusiveUnlockRequest.RequestType = ExclusiveAccessUnlockDevice; - + int err = GetLastError(); + BOOL success = DeviceIoControl((HANDLE)this->osFileHandle, IOCTL_CDROM_EXCLUSIVE_ACCESS, &exclusiveUnlockRequest, sizeof(CDROM_EXCLUSIVE_LOCK), nullptr, 0, &unused, nullptr); if (!success) { - std::cerr << "Error unlocking the drive: " << std::to_string(GetLastError()) << std::endl; + //Utils::ShowErrorMessage("Error Unlocking the drive: " + std::to_string(GetLastError())); } this->MountVolume(); @@ -187,7 +189,7 @@ namespace Li::Scsi { #else #error no way to exclusive unlock drive on this platform. #endif - } + }*/ bool IoCtl::SetDriveSpeed(int readSpeed, int writeSpeed) { @@ -203,7 +205,7 @@ namespace Li::Scsi { BOOL success = DeviceIoControl((HANDLE)this->osFileHandle, IOCTL_CDROM_SET_SPEED, &cdromSetSpeed, sizeof(CDROM_SET_SPEED), nullptr, 0, &unused, nullptr); if (!success) { - std::cerr << "Error setting speed: " << std::to_string(GetLastError()) << std::endl; + Utils::ShowErrorMessage("Error setting speed: " + std::to_string(GetLastError())); } return success; #else diff --git a/DumpDVD/Scsi/IoCtl.hpp b/DumpDVD/Scsi/IoCtl.hpp index ced0d91..3155f4f 100644 --- a/DumpDVD/Scsi/IoCtl.hpp +++ b/DumpDVD/Scsi/IoCtl.hpp @@ -18,10 +18,10 @@ namespace Li::Scsi { uint64_t GetTotalSectors(); bool SetDriveSpeed(int readSpeed, int writeSpeed); bool AllowReadingPastDisc(); - bool ExclusiveLockDrive(); + /*bool ExclusiveLockDrive(); bool ExclusiveUnlockDrive(); bool UnmountVolume(); - bool MountVolume(); + bool MountVolume();*/ std::vector* GetSupportedReadSpeeds(); }; diff --git a/DumpDVD/Scsi/OpticalDrive.cpp b/DumpDVD/Scsi/OpticalDrive.cpp index dd9e9fc..8809c50 100644 --- a/DumpDVD/Scsi/OpticalDrive.cpp +++ b/DumpDVD/Scsi/OpticalDrive.cpp @@ -46,10 +46,11 @@ namespace Li::Scsi { this->hasCss = dvdcss_is_scrambled(ctl->GetDvdCssHandle()); if (this->hasCss) { - this->discKey = (std::byte*)dvdcss_get_cur_disckey(ctl->GetDvdCssHandle()); + std::byte* dkey = (std::byte*)dvdcss_get_cur_disckey(ctl->GetDvdCssHandle()); + memcpy(this->discKey, dkey, sizeof(OpticalDrive::discKey)); } else { - this->discKey = nullptr; + memset(this->discKey, 0, sizeof(OpticalDrive::discKey)); } delete ctl; @@ -92,19 +93,21 @@ namespace Li::Scsi { std::vector* drives = new std::vector(); #ifdef _WIN32 WCHAR* drivesList = new WCHAR[BUFFER_SIZE]; - GetLogicalDriveStrings(BUFFER_SIZE, drivesList); + memset(drivesList, 0x00, sizeof(drivesList)); - WCHAR* curDrive = drivesList; - while (*curDrive != '\0') { + if (GetLogicalDriveStrings(BUFFER_SIZE, drivesList) != 0) { + WCHAR* curDrive = drivesList; + while (*curDrive != '\0') { - UINT driveType = GetDriveType(curDrive); - if (driveType == DRIVE_CDROM) { - std::wstring wDrive = std::wstring(curDrive); - std::string drive = std::string(wDrive.begin(), wDrive.end()); - OpticalDrive* opticalDrive = new OpticalDrive(drive); - drives->push_back(opticalDrive); + UINT driveType = GetDriveType(curDrive); + if (driveType == DRIVE_CDROM) { + std::wstring wDrive = std::wstring(curDrive); + std::string drive = std::string(wDrive.begin(), wDrive.end()); + OpticalDrive* opticalDrive = new OpticalDrive(drive); + drives->push_back(opticalDrive); + } + curDrive += lstrlen(curDrive) + 1; } - curDrive += lstrlen(curDrive) + 1; } delete drivesList; diff --git a/DumpDVD/Scsi/OpticalDrive.hpp b/DumpDVD/Scsi/OpticalDrive.hpp index ab50f4b..077a3d7 100644 --- a/DumpDVD/Scsi/OpticalDrive.hpp +++ b/DumpDVD/Scsi/OpticalDrive.hpp @@ -9,7 +9,7 @@ namespace Li::Scsi { std::string volumeName; bool hasCss; - std::byte* discKey; + std::byte discKey[5]; bool discInDrive; std::vector* supportedSpeeds; diff --git a/DumpDVD/Utils.cpp b/DumpDVD/Utils.cpp index 0564f5d..2f34728 100644 --- a/DumpDVD/Utils.cpp +++ b/DumpDVD/Utils.cpp @@ -24,6 +24,14 @@ namespace Li { return documentsFolder; } + void Utils::ShowErrorMessage(std::string errorMsg) { +#ifdef _WIN32 + std::wstring err = std::wstring(errorMsg.begin(), errorMsg.end()); + MessageBox(NULL, err.c_str(), L"Error", MB_ICONSTOP); +#endif + std::cerr << errorMsg << std::endl; + } + bool Utils::CompareStringCaseInsensitive(std::string input, std::string compare) { unsigned int sz = input.size(); if (compare.size() != sz) diff --git a/DumpDVD/Utils.hpp b/DumpDVD/Utils.hpp index 55f2fc1..80ef2a9 100644 --- a/DumpDVD/Utils.hpp +++ b/DumpDVD/Utils.hpp @@ -5,6 +5,7 @@ namespace Li { public: static std::string GetDocumentsFolder(); static std::string HumanReadableByteStr(uint64_t bytes); + static void ShowErrorMessage(std::string error); static bool CompareStringCaseInsensitive(std::string input, std::string compare); }; } diff --git a/lib/libdvdcss.lib b/lib/libdvdcss.lib index a6d2753c3591033fd2be25254ff79fe281f2600a..d1381717944e0ad019138e4de2b7bc22cc1f9ae2 100644 GIT binary patch delta 15919 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 Q5Vij;)BoW^V|ls%0n~TVxc~qF delta 14816 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 diff --git a/libdvdcss/src/device.c b/libdvdcss/src/device.c index 34b610b..fc41287 100644 --- a/libdvdcss/src/device.c +++ b/libdvdcss/src/device.c @@ -383,7 +383,9 @@ int dvdcss_open_device ( dvdcss_t dvdcss ) dvdcss->pf_seek = win2k_seek; dvdcss->pf_read = win2k_read; dvdcss->pf_readv = win2k_readv; - return win2k_open( dvdcss, psz_device ); + int i_ret = win2k_open( dvdcss, psz_device ); + ioctl_LockVolume(dvdcss->i_fd); + return i_ret; } else #elif defined( __OS2__ ) @@ -395,7 +397,9 @@ int dvdcss_open_device ( dvdcss_t dvdcss ) dvdcss->pf_seek = libc_seek; dvdcss->pf_read = libc_read; dvdcss->pf_readv = libc_readv; - return os2_open( dvdcss, psz_device ); + int i_ret = os2_open( dvdcss, psz_device ); + ioctl_LockVolume(dvdcss->i_fd); + return i_ret; } else #endif @@ -404,7 +408,9 @@ int dvdcss_open_device ( dvdcss_t dvdcss ) dvdcss->pf_seek = libc_seek; dvdcss->pf_read = libc_read; dvdcss->pf_readv = libc_readv; - return libc_open( dvdcss, psz_device ); + int i_ret = libc_open( dvdcss, psz_device ); + ioctl_LockVolume(dvdcss->i_fd); + return i_ret; } } @@ -414,6 +420,8 @@ int dvdcss_close_device ( dvdcss_t dvdcss ) { return 0; } + + ioctl_UnlockVolume(dvdcss->i_fd); #if defined( _WIN32 ) /* Free readv temporary buffer */ diff --git a/libdvdcss/src/ioctl.c b/libdvdcss/src/ioctl.c index 12a9312..753cf5f 100644 --- a/libdvdcss/src/ioctl.c +++ b/libdvdcss/src/ioctl.c @@ -359,6 +359,32 @@ int ioctl_ReadDiscKey( int i_fd, const int *pi_agid, uint8_t *p_key ) return i_ret; } +/***************************************************************************** + * ioctl_LockVolume: deny other processes access to the drive + *****************************************************************************/ +int ioctl_LockVolume(int i_fd) { +#if defined(_WIN32) + DWORD tmp; + int i_ret = DeviceIoControl(i_fd, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &tmp, NULL); + return i_ret; +#else +#error no lock ioctl +#endif +} + +/***************************************************************************** + * ioctl_UnlockVolume: allow access to the drive for other processes + *****************************************************************************/ +int ioctl_UnlockVolume(int i_fd) { +#if defined(_WIN32) + DWORD tmp; + int i_ret = DeviceIoControl(i_fd, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &tmp, NULL); + return i_ret; +#else +#error no unlock ioctl +#endif +} + /***************************************************************************** * ioctl_ReadTitleKey: get the title key *****************************************************************************/ diff --git a/libdvdcss/src/ioctl.h b/libdvdcss/src/ioctl.h index 38524b5..2853ae5 100644 --- a/libdvdcss/src/ioctl.h +++ b/libdvdcss/src/ioctl.h @@ -24,7 +24,6 @@ #define DVDCSS_IOCTL_H #include -int ioctl_SetDriveSpeed ( int, int ); int ioctl_ReadCopyright ( int, int, int * ); int ioctl_ReadDiscKey ( int, const int *, uint8_t * ); int ioctl_ReadTitleKey ( int, const int *, int, uint8_t * ); @@ -36,6 +35,8 @@ int ioctl_InvalidateAgid ( int, int * ); int ioctl_SendChallenge ( int, const int *, const uint8_t * ); int ioctl_SendKey2 ( int, const int *, const uint8_t * ); int ioctl_ReportRPC ( int, int *, int *, int * ); +int ioctl_UnlockVolume ( int ); +int ioctl_LockVolume ( int ); #define DVD_DISCKEY_SIZE 2048