DumpDVD/DumpDVD/Scsi/CdRom.cpp

101 lines
3.3 KiB
C++

#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;
}
}