upload changes
This commit is contained in:
parent
cf46d4693e
commit
b6f21843d0
|
@ -19,18 +19,24 @@
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="DumpDVD.cpp" />
|
<ClCompile Include="Main.cpp" />
|
||||||
<ClCompile Include="Gui\D3D.cpp" />
|
<ClCompile Include="Gui\D3D.cpp" />
|
||||||
|
<ClCompile Include="Gui\DumpDVD.cpp" />
|
||||||
<ClCompile Include="Gui\MainWindow.cpp" />
|
<ClCompile Include="Gui\MainWindow.cpp" />
|
||||||
<ClCompile Include="Gui\SDL.cpp" />
|
<ClCompile Include="Gui\SDL.cpp" />
|
||||||
<ClCompile Include="Scsi\CdRom.cpp" />
|
<ClCompile Include="Scsi\IoCtl.cpp" />
|
||||||
|
<ClCompile Include="Scsi\OpticalDrive.cpp" />
|
||||||
|
<ClCompile Include="Utils.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Gui\D3D.hpp" />
|
<ClInclude Include="Gui\D3D.hpp" />
|
||||||
|
<ClInclude Include="Gui\DumpDVD.hpp" />
|
||||||
<ClInclude Include="Gui\MainWindow.hpp" />
|
<ClInclude Include="Gui\MainWindow.hpp" />
|
||||||
<ClInclude Include="Gui\Renderer.hpp" />
|
<ClInclude Include="Gui\Renderer.hpp" />
|
||||||
<ClInclude Include="Gui\SDL.hpp" />
|
<ClInclude Include="Gui\SDL.hpp" />
|
||||||
<ClInclude Include="Scsi\CdRom.hpp" />
|
<ClInclude Include="Utils.hpp" />
|
||||||
|
<ClInclude Include="Scsi\IoCtl.hpp" />
|
||||||
|
<ClInclude Include="Scsi\OpticalDrive.hpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<VCProjectVersion>16.0</VCProjectVersion>
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
@ -88,9 +94,9 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<AdditionalIncludeDirectories>$(SolutionDir)include\SDL;$(SolutionDir)ImGui;$(SolutionDir)libdvdcss\src\dvdcss;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(SolutionDir)include\PFD;$(SolutionDir)include\SDL;$(SolutionDir)ImGui;$(SolutionDir)libdvdcss\src\dvdcss;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -109,9 +115,9 @@
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>false</SDLCheck>
|
<SDLCheck>false</SDLCheck>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<AdditionalIncludeDirectories>$(SolutionDir)include\SDL;$(SolutionDir)ImGui;$(SolutionDir)libdvdcss\src\dvdcss;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(SolutionDir)include\PFD;$(SolutionDir)include\SDL;$(SolutionDir)ImGui;$(SolutionDir)libdvdcss\src\dvdcss;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||||
|
|
|
@ -15,10 +15,10 @@
|
||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="DumpDVD.cpp">
|
<ClCompile Include="Main.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Scsi\CdRom.cpp">
|
<ClCompile Include="Scsi\IoCtl.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Gui\MainWindow.cpp">
|
<ClCompile Include="Gui\MainWindow.cpp">
|
||||||
|
@ -30,9 +30,18 @@
|
||||||
<ClCompile Include="Gui\SDL.cpp">
|
<ClCompile Include="Gui\SDL.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Scsi\OpticalDrive.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Gui\DumpDVD.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Utils.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Scsi\CdRom.hpp">
|
<ClInclude Include="Scsi\IoCtl.hpp">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Gui\MainWindow.hpp">
|
<ClInclude Include="Gui\MainWindow.hpp">
|
||||||
|
@ -47,5 +56,14 @@
|
||||||
<ClInclude Include="Gui\Renderer.hpp">
|
<ClInclude Include="Gui\Renderer.hpp">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Scsi\OpticalDrive.hpp">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Gui\DumpDVD.hpp">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Utils.hpp">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,315 @@
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <shlobj.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <portable-file-dialogs.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
#include <sstream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include "DumpDVD.hpp"
|
||||||
|
|
||||||
|
#include "../Utils.hpp"
|
||||||
|
#include "../Scsi/IoCtl.hpp"
|
||||||
|
#include "../Scsi/OpticalDrive.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Li::Gui {
|
||||||
|
|
||||||
|
DumpDVD::DumpDVD() {
|
||||||
|
this->keepPolling = true;
|
||||||
|
this->showDemoWindow = true;
|
||||||
|
this->imRippinIt = false;
|
||||||
|
this->error = false;
|
||||||
|
this->done = false;
|
||||||
|
|
||||||
|
this->selectedDrive = 0;
|
||||||
|
this->windowFlags = ImGuiWindowFlags_NoCollapse;
|
||||||
|
this->selectedDriveSpeed = 0;
|
||||||
|
this->counter = 0;
|
||||||
|
|
||||||
|
this->drivesList = Li::Scsi::OpticalDrive::ListOpticalDrives();
|
||||||
|
this->pollDrives = new std::thread(&DumpDVD::pollDrivesThread, this);
|
||||||
|
|
||||||
|
this->sectorsReadSoFar = 0;
|
||||||
|
this->sectorsAtOnce = 0x400;
|
||||||
|
|
||||||
|
this->lock = new std::mutex();
|
||||||
|
|
||||||
|
this->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
DumpDVD::~DumpDVD() {
|
||||||
|
this->keepPolling = false;
|
||||||
|
this->pollDrives->join();
|
||||||
|
delete this->pollDrives;
|
||||||
|
freeOldDriveList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpDVD::ripDiscThread() {
|
||||||
|
std::ofstream* iso = new std::ofstream(std::string(this->outputFile), std::ios::binary);
|
||||||
|
uint64_t totalSectors = this->GetCurrentSelectedDrive()->Sectors();
|
||||||
|
|
||||||
|
std::vector<uint32_t>* speeds = this->GetCurrentSelectedDrive()->SupportedSpeeds();
|
||||||
|
uint32_t speed = 0xFFFF;
|
||||||
|
if (this->selectedDriveSpeed < speeds->size()) {
|
||||||
|
speed = speeds->at(this->selectedDriveSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
Li::Scsi::IoCtl* drive = new Li::Scsi::IoCtl(this->GetCurrentSelectedDrive()->DrivePath());
|
||||||
|
|
||||||
|
drive->AllowReadingPastDisc();
|
||||||
|
drive->SetDriveSpeed(speed, speed);
|
||||||
|
this->sectorsReadSoFar = 0;
|
||||||
|
dvdcss_seek(drive->GetDvdCssHandle(), 0, DVDCSS_SEEK_KEY);
|
||||||
|
|
||||||
|
uint8_t* buffer = new uint8_t[DVDCSS_BLOCK_SIZE * this->sectorsAtOnce];
|
||||||
|
|
||||||
|
do {
|
||||||
|
int sectorsToRead = this->sectorsAtOnce;
|
||||||
|
if ((this->sectorsReadSoFar + sectorsToRead) > totalSectors) {
|
||||||
|
sectorsToRead = totalSectors - this->sectorsReadSoFar;
|
||||||
|
}
|
||||||
|
|
||||||
|
int numRead = dvdcss_read(drive->GetDvdCssHandle(), buffer, sectorsToRead, DVDCSS_READ_DECRYPT);
|
||||||
|
if (numRead <= 0) {
|
||||||
|
this->error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
iso->write((const char*)buffer, DVDCSS_BLOCK_SIZE * numRead);
|
||||||
|
|
||||||
|
this->sectorsReadSoFar += numRead;
|
||||||
|
|
||||||
|
} while (this->sectorsReadSoFar < totalSectors);
|
||||||
|
this->done = true;
|
||||||
|
|
||||||
|
delete buffer;
|
||||||
|
delete drive;
|
||||||
|
iso->close();
|
||||||
|
delete iso;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpDVD::pollDrivesThread() {
|
||||||
|
while (this->keepPolling) {
|
||||||
|
if ( (this->counter % (60 * 10)) == 0) {
|
||||||
|
this->lock->lock();
|
||||||
|
refreshDriveList();
|
||||||
|
this->lock->unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpDVD::refreshDriveList() {
|
||||||
|
std::vector<Li::Scsi::OpticalDrive*>* pollDrives = Li::Scsi::OpticalDrive::ListOpticalDrives();
|
||||||
|
freeOldDriveList();
|
||||||
|
this->drivesList = pollDrives;
|
||||||
|
|
||||||
|
}
|
||||||
|
void DumpDVD::freeOldDriveList() {
|
||||||
|
std::vector<Li::Scsi::OpticalDrive*>* prevList = this->drivesList;
|
||||||
|
this->drivesList = nullptr;
|
||||||
|
|
||||||
|
for (Li::Scsi::OpticalDrive* drive : *prevList) {
|
||||||
|
delete drive;
|
||||||
|
}
|
||||||
|
delete prevList;
|
||||||
|
}
|
||||||
|
std::string DumpDVD::getDrivesStr() {
|
||||||
|
std::string drivesComboBox = "";
|
||||||
|
for (Li::Scsi::OpticalDrive* drive : *this->drivesList) {
|
||||||
|
drivesComboBox += drive->DrivePath() + " - " + drive->VolumeName() + '\0';
|
||||||
|
}
|
||||||
|
return drivesComboBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpDVD::reset() {
|
||||||
|
if (this->GetCurrentSelectedDrive()->DiscInDrive())
|
||||||
|
this->selectedDriveSpeed = this->GetCurrentSelectedDrive()->SupportedSpeeds()->size();
|
||||||
|
else
|
||||||
|
this->selectedDriveSpeed = 0;
|
||||||
|
|
||||||
|
std::string documentsFolder = "";
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
WCHAR documents[MAX_PATH];
|
||||||
|
HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documents);
|
||||||
|
std::wstring wDocuments = std::wstring(documents);
|
||||||
|
documentsFolder = std::string(wDocuments.begin(), wDocuments.end());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::filesystem::path p = std::filesystem::path(documentsFolder);
|
||||||
|
p = p.append(GetCurrentSelectedDrive()->VolumeName()).replace_extension(".iso");
|
||||||
|
strncpy(this->outputFile, p.string().c_str(), sizeof(DumpDVD::outputFile)-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Li::Scsi::OpticalDrive* DumpDVD::GetCurrentSelectedDrive() {
|
||||||
|
return this->drivesList->at(this->selectedDrive);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpDVD::startRip() {
|
||||||
|
refreshDriveList();
|
||||||
|
if (this->GetCurrentSelectedDrive()->DiscInDrive()) {
|
||||||
|
this->keepPolling = false;
|
||||||
|
|
||||||
|
this->pollDrives->join();
|
||||||
|
delete this->pollDrives;
|
||||||
|
|
||||||
|
this->pollDrives = new std::thread(&DumpDVD::ripDiscThread, this);
|
||||||
|
|
||||||
|
this->imRippinIt = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpDVD::endRipAndGoBackToMenu() {
|
||||||
|
this->done = false;
|
||||||
|
this->imRippinIt = false;
|
||||||
|
this->reset();
|
||||||
|
this->sectorsReadSoFar = 0;
|
||||||
|
this->pollDrives->join();
|
||||||
|
delete this->pollDrives;
|
||||||
|
|
||||||
|
this->drivesList = Li::Scsi::OpticalDrive::ListOpticalDrives();
|
||||||
|
this->pollDrives = new std::thread(&DumpDVD::pollDrivesThread, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void DumpDVD::showRippingStatus() {
|
||||||
|
ImGui::SeparatorText("Status");
|
||||||
|
float percentage = (((float)this->sectorsReadSoFar / (float)this->GetCurrentSelectedDrive()->Sectors()));
|
||||||
|
ImGui::Text("Copying Disc ... ", (int)percentage);
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::ProgressBar(percentage);
|
||||||
|
|
||||||
|
ImGui::Text("Sector %lli / %lli", this->sectorsReadSoFar, this->GetCurrentSelectedDrive()->Sectors());
|
||||||
|
|
||||||
|
uint64_t szSoFar = this->sectorsReadSoFar * DVDCSS_BLOCK_SIZE;
|
||||||
|
uint64_t szTotal = this->GetCurrentSelectedDrive()->Sectors() * DVDCSS_BLOCK_SIZE;
|
||||||
|
|
||||||
|
|
||||||
|
ImGui::Text("Total %s / %s", Utils::HumanReadableByteStr(szSoFar).c_str(), Utils::HumanReadableByteStr(szTotal).c_str());
|
||||||
|
|
||||||
|
if (this->done) {
|
||||||
|
if (!this->error) {
|
||||||
|
ImGui::Begin("Complete", &done, this->windowFlags);
|
||||||
|
ImGui::Text("ISO file was created successfully.");
|
||||||
|
if (ImGui::Button("OK")) {
|
||||||
|
this->endRipAndGoBackToMenu();
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ImGui::Begin("Error", &done, this->windowFlags);
|
||||||
|
ImGui::Text("Error occured when creating an ISO");
|
||||||
|
if (ImGui::Button("OK")) {
|
||||||
|
this->endRipAndGoBackToMenu();
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpDVD::showRipMenu() {
|
||||||
|
this->lock->lock();
|
||||||
|
|
||||||
|
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 ...");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
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("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();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpDVD::RenderUI() {
|
||||||
|
if (this->drivesList == nullptr) return;
|
||||||
|
|
||||||
|
const ImGuiViewport* mainViewport = ImGui::GetMainViewport();
|
||||||
|
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Appearing);
|
||||||
|
ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize, ImGuiCond_Appearing);
|
||||||
|
|
||||||
|
ImGui::Begin("DVD Dumper", NULL, windowFlags);
|
||||||
|
|
||||||
|
if (this->imRippinIt)
|
||||||
|
{
|
||||||
|
this->showRippingStatus();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->showRipMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (showDemoWindow)
|
||||||
|
ImGui::ShowDemoWindow(&showDemoWindow);
|
||||||
|
#endif
|
||||||
|
this->counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
#ifndef _LI_DUMP_DVD_H
|
||||||
|
#define _LI_DUMP_DVD_H 1
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "../Scsi/IoCtl.hpp"
|
||||||
|
#include "../Scsi/OpticalDrive.hpp"
|
||||||
|
|
||||||
|
namespace Li::Gui {
|
||||||
|
|
||||||
|
class DumpDVD {
|
||||||
|
private:
|
||||||
|
bool keepPolling;
|
||||||
|
bool showDemoWindow;
|
||||||
|
bool imRippinIt; // dodododo do do!
|
||||||
|
|
||||||
|
std::mutex* lock;
|
||||||
|
|
||||||
|
bool error;
|
||||||
|
bool done;
|
||||||
|
uint64_t sectorsReadSoFar;
|
||||||
|
int sectorsAtOnce;
|
||||||
|
|
||||||
|
int selectedDrive;
|
||||||
|
ImGuiWindowFlags windowFlags;
|
||||||
|
int selectedDriveSpeed;
|
||||||
|
uint32_t counter;
|
||||||
|
char outputFile[0x8000];
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<Li::Scsi::OpticalDrive*>* drivesList;
|
||||||
|
std::thread* pollDrives;
|
||||||
|
|
||||||
|
void ripDiscThread();
|
||||||
|
void pollDrivesThread();
|
||||||
|
|
||||||
|
void freeOldDriveList();
|
||||||
|
void refreshDriveList();
|
||||||
|
std::string getDrivesStr();
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
void startRip();
|
||||||
|
void endRipAndGoBackToMenu();
|
||||||
|
|
||||||
|
void showRipMenu();
|
||||||
|
void showRippingStatus();
|
||||||
|
|
||||||
|
public:
|
||||||
|
Li::Scsi::OpticalDrive* GetCurrentSelectedDrive();
|
||||||
|
DumpDVD();
|
||||||
|
~DumpDVD();
|
||||||
|
void RenderUI();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -11,65 +11,27 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "SDL.hpp"
|
#include "SDL.hpp"
|
||||||
#include "../Scsi/CdRom.hpp"
|
#include "DumpDVD.hpp"
|
||||||
|
|
||||||
namespace Li::Gui {
|
namespace Li::Gui {
|
||||||
|
|
||||||
std::string getDrivesList() {
|
|
||||||
std::vector<std::string>* drives = Li::Scsi::CdRom::ListOpticalDrives();
|
|
||||||
|
|
||||||
std::string drivesComboBox = "";
|
|
||||||
for (std::string drive : *drives) {
|
|
||||||
drivesComboBox += drive + '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
return drivesComboBox;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainWindow::MainWindow() {
|
MainWindow::MainWindow() {
|
||||||
this->sdl = new SDL("DumpDVD", 800, 400);
|
this->sdl = new SDL("DumpDVD", 800, 400);
|
||||||
bool showDemoWindow = true;
|
|
||||||
int selectedDrive = 0;
|
|
||||||
ImGuiWindowFlags windowFlags = 0;
|
|
||||||
windowFlags |= ImGuiWindowFlags_NoCollapse;
|
|
||||||
int selectedDriveSpeed = 22;
|
|
||||||
|
|
||||||
std::string drives = getDrivesList();
|
DumpDVD* dumpDvdMenu = new DumpDVD();
|
||||||
|
|
||||||
while (!this->sdl->IsExiting()) {
|
while (!this->sdl->IsExiting()) {
|
||||||
this->sdl->PollEvent();
|
this->sdl->PollEvent();
|
||||||
this->sdl->NewFrame();
|
this->sdl->NewFrame();
|
||||||
|
|
||||||
const ImGuiViewport* mainViewport = ImGui::GetMainViewport();
|
dumpDvdMenu->RenderUI();
|
||||||
ImGui::SetNextWindowPos(ImVec2(mainViewport->WorkPos.x, mainViewport->WorkPos.y), ImGuiCond_FirstUseEver);
|
|
||||||
ImGui::SetNextWindowSize(ImVec2(550, 680), ImGuiCond_FirstUseEver);
|
|
||||||
|
|
||||||
ImGui::Begin("DVD Dumper", NULL, windowFlags);
|
|
||||||
ImGui::Text("Select Drive:");
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Combo("", &selectedDrive, drives.c_str());
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (ImGui::Button("Refresh", ImVec2(70, 20))) {
|
|
||||||
drives = getDrivesList();
|
|
||||||
}
|
|
||||||
|
|
||||||
const int numDrvSpeeds = 23;
|
|
||||||
const char* driveSepeds[numDrvSpeeds] = { "1x", "2x", "2.4x", "3x", "4x", "5x",
|
|
||||||
"6x", "8x", "10x", "12x", "14x", "16x",
|
|
||||||
"18x", "20x", "22x", "24x", "32x", "40x",
|
|
||||||
"44x", "48x", "52x", "56x", "MAX"};
|
|
||||||
const char* driveSpeedName = (selectedDriveSpeed >= 0 && selectedDriveSpeed < numDrvSpeeds) ? driveSepeds[selectedDriveSpeed] : "Unknown";
|
|
||||||
ImGui::Text("Read Speed:");
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::SliderInt("", &selectedDriveSpeed, 0, numDrvSpeeds - 1, driveSpeedName);
|
|
||||||
|
|
||||||
ImGui::End();
|
|
||||||
if (showDemoWindow)
|
|
||||||
ImGui::ShowDemoWindow(&showDemoWindow);
|
|
||||||
|
|
||||||
this->sdl->Render();
|
this->sdl->Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete dumpDvdMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() {
|
MainWindow::~MainWindow() {
|
||||||
|
|
|
@ -33,7 +33,8 @@ namespace Li::Gui {
|
||||||
|
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.IniFilename = nullptr;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
|
@ -53,9 +54,9 @@ namespace Li::Gui {
|
||||||
{
|
{
|
||||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||||
if (event.type == SDL_QUIT)
|
if (event.type == SDL_QUIT)
|
||||||
isExiting = true;
|
this->isExiting = true;
|
||||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
|
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
|
||||||
isExiting = true;
|
this->isExiting = true;
|
||||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window))
|
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window))
|
||||||
{
|
{
|
||||||
// Release all outstanding references to the swap chain's buffers before resizing.
|
// Release all outstanding references to the swap chain's buffers before resizing.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "Gui\MainWindow.hpp"
|
#include "Gui/MainWindow.hpp"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
@ -12,10 +12,6 @@
|
||||||
|
|
||||||
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow)
|
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
|
||||||
AllocConsole();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Li::Gui::MainWindow* mainWindow = new Li::Gui::MainWindow();
|
Li::Gui::MainWindow* mainWindow = new Li::Gui::MainWindow();
|
||||||
delete mainWindow;
|
delete mainWindow;
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
#include "CdRom.hpp"
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
#define _NTSCSI_USER_MODE_ 1
|
|
||||||
#include <windows.h>
|
|
||||||
#include <winioctl.h>
|
|
||||||
#include <ntddcdrm.h>
|
|
||||||
#include <ntddcdvd.h>
|
|
||||||
#include <ntddmmc.h>
|
|
||||||
#include <ntddscsi.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <scsi.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <dvdcss.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace Li::Scsi {
|
|
||||||
CdRom::CdRom(std::string drive) {
|
|
||||||
this->dvdCssHandle = dvdcss_open(drive.c_str());
|
|
||||||
this->osFileHandle = dvdcss_get_raw_fd(this->dvdCssHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
CdRom::~CdRom() {
|
|
||||||
dvdcss_close(this->dvdCssHandle);
|
|
||||||
this->dvdCssHandle = NULL;
|
|
||||||
this->osFileHandle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t CdRom::GetTotalSectors() {
|
|
||||||
#ifdef _WIN32
|
|
||||||
DISK_GEOMETRY_EX geo;
|
|
||||||
memset(&geo, 0x00, sizeof(DISK_GEOMETRY_EX));
|
|
||||||
|
|
||||||
DWORD unused;
|
|
||||||
BOOL success = DeviceIoControl((HANDLE)this->osFileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, nullptr, 0, &geo, sizeof(DISK_GEOMETRY_EX), &unused, nullptr);
|
|
||||||
if (!success) {
|
|
||||||
std::cerr << "Error getting geometry: " << std::to_string(GetLastError()) << std::endl;
|
|
||||||
}
|
|
||||||
return (size_t)(geo.DiskSize.QuadPart / 2048);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
bool CdRom::AllowReadingPastDisc() {
|
|
||||||
#ifdef _WIN32
|
|
||||||
// On windows, you cannot read anything outside the last session of the disc, unless you enable this
|
|
||||||
// this means you cannot read the Lead-Out, *or* double densitity DVDs
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
bool CdRom::SetDriveSpeed(short readSpeed, short writeSpeed)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
DWORD unused;
|
|
||||||
CDROM_SET_SPEED cdromSetSpeed;
|
|
||||||
memset(&cdromSetSpeed, 0x00, sizeof(CDROM_SET_SPEED));
|
|
||||||
|
|
||||||
cdromSetSpeed.RequestType = CdromSetSpeed;
|
|
||||||
cdromSetSpeed.ReadSpeed = readSpeed;
|
|
||||||
cdromSetSpeed.WriteSpeed = writeSpeed;
|
|
||||||
cdromSetSpeed.RotationControl = CdromDefaultRotation;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string>* CdRom::ListOpticalDrives() {
|
|
||||||
std::vector<std::string>* drives = new std::vector<std::string>();
|
|
||||||
#ifdef _WIN32
|
|
||||||
const size_t drivesListSz = 0x1000;
|
|
||||||
WCHAR* drivesList = new WCHAR[drivesListSz];
|
|
||||||
GetLogicalDriveStrings(drivesListSz, drivesList);
|
|
||||||
|
|
||||||
WCHAR* curDrive = drivesList;
|
|
||||||
while (*curDrive != '\0') {
|
|
||||||
|
|
||||||
UINT driveType = GetDriveType(curDrive);
|
|
||||||
if (driveType == DRIVE_CDROM) {
|
|
||||||
std::wstring wstr = std::wstring(curDrive);
|
|
||||||
std::string cdromDrive = std::string(wstr.begin(), wstr.end());
|
|
||||||
cdromDrive = cdromDrive.substr(0, cdromDrive.size() - 1);
|
|
||||||
drives->push_back(cdromDrive);
|
|
||||||
}
|
|
||||||
curDrive += lstrlen(curDrive) + 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return drives;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
#include "IoCtl.hpp"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#define _NTSCSI_USER_MODE_ 1
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winioctl.h>
|
||||||
|
#include <ntddcdrm.h>
|
||||||
|
#include <ntddcdvd.h>
|
||||||
|
#include <ntddmmc.h>
|
||||||
|
#include <ntddscsi.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <scsi.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <dvdcss.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Li::Scsi {
|
||||||
|
IoCtl::IoCtl(std::string drive) {
|
||||||
|
this->dvdCssHandle = dvdcss_open(drive.c_str());
|
||||||
|
this->osFileHandle = dvdcss_get_raw_fd(this->dvdCssHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
IoCtl::~IoCtl() {
|
||||||
|
dvdcss_close(this->dvdCssHandle);
|
||||||
|
this->dvdCssHandle = NULL;
|
||||||
|
this->osFileHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t>* IoCtl::GetSupportedReadSpeeds() {
|
||||||
|
std::vector<uint32_t>* speeds = new std::vector<uint32_t>();
|
||||||
|
#ifdef _WIN32
|
||||||
|
CDROM_PERFORMANCE_REQUEST perfRequest;
|
||||||
|
memset(&perfRequest, 0x00, sizeof(CDROM_PERFORMANCE_REQUEST));
|
||||||
|
perfRequest.RequestType = CdromPerformanceRequest;
|
||||||
|
perfRequest.PerformanceType = CdromReadPerformance;
|
||||||
|
perfRequest.Exceptions = CdromNominalPerformance;
|
||||||
|
perfRequest.Tolerance = Cdrom10Nominal20Exceptions;
|
||||||
|
perfRequest.StaringLba = 0;
|
||||||
|
|
||||||
|
uint64_t sz = sizeof(CDROM_PERFORMANCE_HEADER) * 0x1000;
|
||||||
|
byte* buffer = new byte[sz];
|
||||||
|
memset(buffer, 0x00, sz);
|
||||||
|
|
||||||
|
CDROM_PERFORMANCE_HEADER* perfHeader = (CDROM_PERFORMANCE_HEADER*)buffer;
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t dataLen = _byteswap_ulong(*(uint32_t*)perfHeader->DataLength);
|
||||||
|
uint64_t count = dataLen / sizeof(CDROM_NOMINAL_PERFORMANCE_DESCRIPTOR);
|
||||||
|
CDROM_NOMINAL_PERFORMANCE_DESCRIPTOR* pptr = (CDROM_NOMINAL_PERFORMANCE_DESCRIPTOR*)perfHeader->Data;
|
||||||
|
for (uint64_t i = 0; i < count; i++) {
|
||||||
|
CDROM_NOMINAL_PERFORMANCE_DESCRIPTOR perfDesc = pptr[i];
|
||||||
|
uint32_t startPerf = _byteswap_ulong(*(uint32_t*)perfDesc.StartPerformance);
|
||||||
|
uint32_t endPerf = _byteswap_ulong(*(uint32_t*)perfDesc.EndPerformance);
|
||||||
|
|
||||||
|
bool startAlreadyInList = false;
|
||||||
|
bool endAlreadyInList = false;
|
||||||
|
|
||||||
|
for (uint32_t speed : *speeds) {
|
||||||
|
if (speed == startPerf) {
|
||||||
|
startAlreadyInList = true;
|
||||||
|
}
|
||||||
|
if (speed == startPerf) {
|
||||||
|
endAlreadyInList = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!startAlreadyInList)
|
||||||
|
speeds->push_back(startPerf);
|
||||||
|
|
||||||
|
if(!endAlreadyInList)
|
||||||
|
speeds->push_back(endPerf);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete buffer;
|
||||||
|
#endif
|
||||||
|
return speeds;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t IoCtl::GetTotalSectors() {
|
||||||
|
#ifdef _WIN32
|
||||||
|
DISK_GEOMETRY_EX geometry;
|
||||||
|
memset(&geometry, 0x00, sizeof(DISK_GEOMETRY_EX));
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return (uint64_t)(geometry.DiskSize.QuadPart / DVDCSS_BLOCK_SIZE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
bool IoCtl::AllowReadingPastDisc() {
|
||||||
|
#ifdef _WIN32
|
||||||
|
// On windows, you cannot read anything outside the last session of the disc, unless you enable this
|
||||||
|
// this means you cannot read the Lead-Out, *or* double densitity DVDs
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
bool IoCtl::SetDriveSpeed(int readSpeed, int writeSpeed)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
DWORD unused;
|
||||||
|
CDROM_SET_SPEED cdromSetSpeed;
|
||||||
|
memset(&cdromSetSpeed, 0x00, sizeof(CDROM_SET_SPEED));
|
||||||
|
|
||||||
|
cdromSetSpeed.RequestType = CdromSetSpeed;
|
||||||
|
cdromSetSpeed.ReadSpeed = (uint16_t)readSpeed;
|
||||||
|
cdromSetSpeed.WriteSpeed = (uint16_t)writeSpeed;
|
||||||
|
cdromSetSpeed.RotationControl = CdromDefaultRotation;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dvdcss_t IoCtl::GetDvdCssHandle() {
|
||||||
|
return this->dvdCssHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,18 +6,20 @@
|
||||||
#include <dvdcss.h>
|
#include <dvdcss.h>
|
||||||
|
|
||||||
namespace Li::Scsi {
|
namespace Li::Scsi {
|
||||||
class CdRom {
|
class IoCtl {
|
||||||
private:
|
private:
|
||||||
dvdcss_t dvdCssHandle;
|
dvdcss_t dvdCssHandle;
|
||||||
int osFileHandle;
|
int osFileHandle;
|
||||||
public:
|
public:
|
||||||
CdRom(std::string drive);
|
IoCtl(std::string drive);
|
||||||
~CdRom();
|
~IoCtl();
|
||||||
|
|
||||||
size_t GetTotalSectors();
|
dvdcss_t GetDvdCssHandle();
|
||||||
bool SetDriveSpeed(short readSpeed, short writeSpeed);
|
uint64_t GetTotalSectors();
|
||||||
|
bool SetDriveSpeed(int readSpeed, int writeSpeed);
|
||||||
bool AllowReadingPastDisc();
|
bool AllowReadingPastDisc();
|
||||||
static std::vector<std::string>* ListOpticalDrives();
|
std::vector<uint32_t>* GetSupportedReadSpeeds();
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
|
@ -0,0 +1,95 @@
|
||||||
|
#include "OpticalDrive.hpp"
|
||||||
|
#include "IoCtl.hpp"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BUFFER_SIZE (0x1000)
|
||||||
|
#define NODISC ("NO DISC")
|
||||||
|
|
||||||
|
namespace Li::Scsi {
|
||||||
|
|
||||||
|
|
||||||
|
void OpticalDrive::getDriveInformation(std::string drv) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
this->drivePath = drv.substr(0, drv.size() - 1);
|
||||||
|
|
||||||
|
std::wstring wdrive = std::wstring(this->drivePath.begin(), this->drivePath.end());
|
||||||
|
WCHAR* wChrVolumeName = new WCHAR[BUFFER_SIZE];
|
||||||
|
|
||||||
|
if (!GetVolumeInformation(wdrive.c_str(), wChrVolumeName, BUFFER_SIZE, NULL, NULL, NULL, NULL, NULL))
|
||||||
|
{
|
||||||
|
this->volumeName = NODISC;
|
||||||
|
this->discInDrive = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::wstring wVolumeName = std::wstring(wChrVolumeName);
|
||||||
|
this->volumeName = std::string(wVolumeName.begin(), wVolumeName.end());
|
||||||
|
this->discInDrive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete wChrVolumeName;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
OpticalDrive::OpticalDrive(std::string drv) {
|
||||||
|
this->getDriveInformation(drv);
|
||||||
|
|
||||||
|
if (this->discInDrive) {
|
||||||
|
IoCtl* ctl = new IoCtl(this->drivePath);
|
||||||
|
this->supportedSpeeds = ctl->GetSupportedReadSpeeds();
|
||||||
|
this->sectors = ctl->GetTotalSectors();
|
||||||
|
delete ctl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OpticalDrive::~OpticalDrive() {
|
||||||
|
if(this->discInDrive)
|
||||||
|
delete this->supportedSpeeds;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t>* OpticalDrive::SupportedSpeeds() {
|
||||||
|
return this->supportedSpeeds;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string OpticalDrive::VolumeName() {
|
||||||
|
return this->volumeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string OpticalDrive::DrivePath() {
|
||||||
|
return this->drivePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t OpticalDrive::Sectors() {
|
||||||
|
return this->sectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpticalDrive::DiscInDrive() {
|
||||||
|
return this->discInDrive;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<OpticalDrive*>* OpticalDrive::ListOpticalDrives() {
|
||||||
|
std::vector<OpticalDrive*>* drives = new std::vector<OpticalDrive*>();
|
||||||
|
#ifdef _WIN32
|
||||||
|
WCHAR* drivesList = new WCHAR[BUFFER_SIZE];
|
||||||
|
GetLogicalDriveStrings(BUFFER_SIZE, drivesList);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
curDrive += lstrlen(curDrive) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete drivesList;
|
||||||
|
#endif
|
||||||
|
return drives;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef _LI_OPTICAL_DRIVE_H
|
||||||
|
#define _LI_OPTICAL_DRIVE_H 1
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
namespace Li::Scsi {
|
||||||
|
class OpticalDrive {
|
||||||
|
private:
|
||||||
|
std::string drivePath;
|
||||||
|
std::string volumeName;
|
||||||
|
|
||||||
|
bool discInDrive;
|
||||||
|
std::vector<uint32_t>* supportedSpeeds;
|
||||||
|
uint64_t sectors;
|
||||||
|
|
||||||
|
void getDriveInformation(std::string drv);
|
||||||
|
public:
|
||||||
|
OpticalDrive(std::string drv);
|
||||||
|
~OpticalDrive();
|
||||||
|
|
||||||
|
std::vector<uint32_t>* SupportedSpeeds();
|
||||||
|
std::string DrivePath();
|
||||||
|
std::string VolumeName();
|
||||||
|
uint64_t Sectors();
|
||||||
|
bool DiscInDrive();
|
||||||
|
|
||||||
|
static std::vector<OpticalDrive*>* ListOpticalDrives();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "Utils.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Li {
|
||||||
|
std::string Utils::HumanReadableByteStr(uint64_t bytes)
|
||||||
|
{
|
||||||
|
const char* suffix[5] = { "B", "KB", "MB", "GB", "TB" };
|
||||||
|
char length = sizeof(suffix) / sizeof(suffix[0]);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
double dblBytes = bytes;
|
||||||
|
|
||||||
|
if (bytes > 1024) {
|
||||||
|
for (i = 0; (bytes / 1024) > 0 && i < length - 1; i++, bytes /= 1024)
|
||||||
|
dblBytes = bytes / 1024.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char output[0x8000];
|
||||||
|
std::snprintf(output, sizeof(output), "%.02lf %s", dblBytes, suffix[i]);
|
||||||
|
return std::string(output);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef _LI_UTILS
|
||||||
|
#include <string>
|
||||||
|
namespace Li {
|
||||||
|
class Utils {
|
||||||
|
public:
|
||||||
|
static std::string HumanReadableByteStr(uint64_t bytes);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -1,45 +0,0 @@
|
||||||
[Window][Debug##Default]
|
|
||||||
Pos=122,92
|
|
||||||
Size=400,400
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Dear ImGui Demo]
|
|
||||||
Pos=476,67
|
|
||||||
Size=550,679
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Hello, world!]
|
|
||||||
Pos=60,60
|
|
||||||
Size=339,180
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][DVD Dumper]
|
|
||||||
Pos=71,27
|
|
||||||
Size=1333,735
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Example: Console]
|
|
||||||
Pos=345,114
|
|
||||||
Size=520,600
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Example: Custom rendering]
|
|
||||||
Pos=60,60
|
|
||||||
Size=485,414
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Same title as another window##2]
|
|
||||||
Pos=491,274
|
|
||||||
Size=451,61
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][###AnimatedTitle]
|
|
||||||
Pos=489,380
|
|
||||||
Size=247,48
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Same title as another window##1]
|
|
||||||
Pos=473,190
|
|
||||||
Size=451,61
|
|
||||||
Collapsed=0
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue