From 7eeee60df5b8d189c7183f05f466f3f0a56863c6 Mon Sep 17 00:00:00 2001 From: Li Date: Thu, 16 Mar 2023 21:35:31 +1300 Subject: [PATCH] Update --- DumpDVD/Gui/DumpDVD.cpp | 39 ++++++++++++++++++-------- DumpDVD/Gui/DumpDVD.hpp | 2 ++ DumpDVD/Scsi/IoCtl.cpp | 62 +++++++++++++++++++++++++++++++++++++++++ DumpDVD/Scsi/IoCtl.hpp | 4 +++ 4 files changed, 96 insertions(+), 11 deletions(-) diff --git a/DumpDVD/Gui/DumpDVD.cpp b/DumpDVD/Gui/DumpDVD.cpp index 737d7f3..2d9382a 100644 --- a/DumpDVD/Gui/DumpDVD.cpp +++ b/DumpDVD/Gui/DumpDVD.cpp @@ -25,6 +25,7 @@ namespace Li::Gui { DumpDVD::DumpDVD() { + this->discInserted = false; this->keepPolling = true; this->showDemoWindow = true; this->imRippinIt = false; @@ -69,6 +70,7 @@ namespace Li::Gui { drive->AllowReadingPastDisc(); drive->SetDriveSpeed(speed, speed); + drive->ExclusiveLockDrive(); this->sectorsReadSoFar = 0; dvdcss_seek(drive->GetDvdCssHandle(), 0, DVDCSS_SEEK_KEY); @@ -81,21 +83,24 @@ namespace Li::Gui { } int numRead = dvdcss_read(drive->GetDvdCssHandle(), buffer, sectorsToRead, DVDCSS_READ_DECRYPT); + if (numRead <= 0) { this->error = true; + this->errorMsg = std::string(dvdcss_error(drive->GetDvdCssHandle())); break; } iso->write((const char*)buffer, DVDCSS_BLOCK_SIZE * numRead); - this->sectorsReadSoFar += numRead; - } while (this->sectorsReadSoFar < totalSectors); - this->done = true; + } while (this->sectorsReadSoFar < totalSectors && this->imRippinIt); + + drive->ExclusiveUnlockDrive(); + iso->close(); + this->done = true; delete buffer; delete drive; - iso->close(); delete iso; } @@ -109,12 +114,10 @@ namespace Li::Gui { void DumpDVD::refreshDriveList() { std::vector* pollDrives = Li::Scsi::OpticalDrive::ListOpticalDrives(); - if(this->lock != nullptr) - this->lock->lock(); + this->lock->lock(); this->freeOldDriveList(); this->drivesList = pollDrives; - if (this->lock != nullptr) - this->lock->unlock(); + this->lock->unlock(); } void DumpDVD::freeOldDriveList() { @@ -165,7 +168,6 @@ namespace Li::Gui { delete this->pollDrives; this->pollDrives = new std::thread(&DumpDVD::ripDiscThread, this); - this->imRippinIt = true; } } @@ -175,9 +177,10 @@ namespace Li::Gui { this->imRippinIt = false; this->reset(); this->sectorsReadSoFar = 0; + this->counter = 0; this->pollDrives->join(); - delete this->pollDrives; + this->keepPolling = true; this->drivesList = Li::Scsi::OpticalDrive::ListOpticalDrives(); this->pollDrives = new std::thread(&DumpDVD::pollDrivesThread, this); } @@ -198,6 +201,12 @@ namespace Li::Gui { ImGui::Text("Total %s / %s", Utils::HumanReadableByteStr(szSoFar).c_str(), Utils::HumanReadableByteStr(szTotal).c_str()); + ImGui::Text("Output file: \"%s\"", this->outputFile); + + if (ImGui::Button("Cancel")) { + this->endRipAndGoBackToMenu(); + std::filesystem::remove(std::string(this->outputFile)); + } if (this->done) { if (!this->error) { @@ -210,13 +219,16 @@ namespace Li::Gui { } else { ImGui::Begin("Error", &done, this->windowFlags); - ImGui::Text("Error occured when creating an ISO"); + ImGui::Text("Error occured when creating an ISO\n\"%s\"", this->errorMsg.c_str()); if (ImGui::Button("OK")) { this->endRipAndGoBackToMenu(); + std::filesystem::remove(std::string(this->outputFile)); } ImGui::End(); } } + + } void DumpDVD::showRipMenu() { @@ -234,8 +246,13 @@ namespace Li::Gui { if (!GetCurrentSelectedDrive()->DiscInDrive()) { ImGui::Text("Put a disc in the drive to continue ..."); + this->discInserted = false; } else { + if (!this->discInserted) { + this->discInserted = true; + this->reset(); + } int numDrvSpeeds = GetCurrentSelectedDrive()->SupportedSpeeds()->size() + 1; std::string driveSpeedName = "Unknown"; diff --git a/DumpDVD/Gui/DumpDVD.hpp b/DumpDVD/Gui/DumpDVD.hpp index fb8dbe3..cc84fbe 100644 --- a/DumpDVD/Gui/DumpDVD.hpp +++ b/DumpDVD/Gui/DumpDVD.hpp @@ -20,9 +20,11 @@ namespace Li::Gui { bool error; bool done; + std::string errorMsg; uint64_t sectorsReadSoFar; int sectorsAtOnce; + bool discInserted; int selectedDrive; ImGuiWindowFlags windowFlags; int selectedDriveSpeed; diff --git a/DumpDVD/Scsi/IoCtl.cpp b/DumpDVD/Scsi/IoCtl.cpp index 0da2ca2..62894aa 100644 --- a/DumpDVD/Scsi/IoCtl.cpp +++ b/DumpDVD/Scsi/IoCtl.cpp @@ -112,6 +112,68 @@ namespace Li::Scsi { return success; #endif } + + 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; + } + return success; +#endif + } + + bool IoCtl::MountVolume() { +#ifdef _WIN32 + 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; + } + return success; +#endif + } + + bool IoCtl::ExclusiveLockDrive() { +#ifdef _WIN32 + + this->UnmountVolume(); + + DWORD unused; + CDROM_EXCLUSIVE_LOCK exclusiveLockRequest; + memset(&exclusiveLockRequest, 0x00, sizeof(CDROM_EXCLUSIVE_LOCK)); + + exclusiveLockRequest.Access.RequestType = ExclusiveAccessLockDevice; + exclusiveLockRequest.Access.Flags = CDROM_LOCK_IGNORE_VOLUME; + + 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; + } + return success; +#endif + } + + bool IoCtl::ExclusiveUnlockDrive() { +#ifdef _WIN32 + DWORD unused; + CDROM_EXCLUSIVE_ACCESS exclusiveUnlockRequest; + memset(&exclusiveUnlockRequest, 0x00, sizeof(CDROM_EXCLUSIVE_ACCESS)); + exclusiveUnlockRequest.RequestType = ExclusiveAccessUnlockDevice; + + 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; + } + + this->MountVolume(); + return success; +#endif + } + bool IoCtl::SetDriveSpeed(int readSpeed, int writeSpeed) { #ifdef _WIN32 diff --git a/DumpDVD/Scsi/IoCtl.hpp b/DumpDVD/Scsi/IoCtl.hpp index 74e43e2..ced0d91 100644 --- a/DumpDVD/Scsi/IoCtl.hpp +++ b/DumpDVD/Scsi/IoCtl.hpp @@ -18,6 +18,10 @@ namespace Li::Scsi { uint64_t GetTotalSectors(); bool SetDriveSpeed(int readSpeed, int writeSpeed); bool AllowReadingPastDisc(); + bool ExclusiveLockDrive(); + bool ExclusiveUnlockDrive(); + bool UnmountVolume(); + bool MountVolume(); std::vector* GetSupportedReadSpeeds(); };