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