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 a6d2753..d138171 100644 Binary files a/lib/libdvdcss.lib and b/lib/libdvdcss.lib differ 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