File indexing completed on 2024-05-26 04:05:40
0001 /* 0002 SPDX-FileCopyrightText: 2013 Patrick von Reth <vonreth@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "winopticaldrive.h" 0008 0009 #include <ntddcdrm.h> 0010 #include <ntddmmc.h> 0011 0012 using namespace Solid::Backends::Win; 0013 0014 WinOpticalDrive::WinOpticalDrive(WinDevice *device) 0015 : WinStorageDrive(device) 0016 { 0017 const QMap<ulong, MediaProfiles> profiles = MediaProfiles::profiles(WinBlock::driveLetterFromUdi(m_device->udi())); 0018 for (const MediaProfiles &p : profiles) { 0019 m_supportedTypes |= p.type; 0020 } 0021 } 0022 0023 WinOpticalDrive::~WinOpticalDrive() 0024 { 0025 } 0026 0027 Solid::OpticalDrive::MediumTypes WinOpticalDrive::supportedMedia() const 0028 { 0029 return m_supportedTypes; 0030 } 0031 0032 bool WinOpticalDrive::eject() 0033 { 0034 WinDeviceManager::deviceAction(WinBlock::driveLetterFromUdi(m_device->udi()), IOCTL_STORAGE_EJECT_MEDIA); 0035 return true; 0036 } 0037 0038 QList<int> WinOpticalDrive::writeSpeeds() const 0039 { 0040 return QList<int>(); 0041 } 0042 0043 int WinOpticalDrive::writeSpeed() const 0044 { 0045 return 0; 0046 } 0047 0048 int WinOpticalDrive::readSpeed() const 0049 { 0050 return 0; 0051 } 0052 0053 MediaProfiles::MediaProfiles() 0054 : profile(0) 0055 , type(0) 0056 , active(false) 0057 { 0058 } 0059 0060 MediaProfiles::MediaProfiles(ulong profile, Solid::OpticalDrive::MediumTypes type, QString name) 0061 : profile(profile) 0062 , type(type) 0063 , name(name) 0064 , active(false) 0065 { 0066 } 0067 0068 MediaProfiles::MediaProfiles(FEATURE_DATA_PROFILE_LIST_EX *feature) 0069 : profile(0) 0070 , type(0) 0071 , active(false) 0072 { 0073 ulong val = (feature->ProfileNumber[0] << 8 | feature->ProfileNumber[1] << 0); 0074 MediaProfiles p = MediaProfiles::getProfile(val); 0075 if (!p.isNull()) { 0076 profile = p.profile; 0077 type = p.type; 0078 name = p.name; 0079 active = feature->Current; 0080 } 0081 } 0082 0083 bool MediaProfiles::isNull() 0084 { 0085 return name.isNull(); 0086 } 0087 0088 QMap<ulong, MediaProfiles> MediaProfiles::profiles(const QString &drive) 0089 { 0090 // thx to http://www.adras.com/Determine-optical-drive-type-and-capabilities.t6826-144-1.html 0091 0092 QMap<ulong, MediaProfiles> out; 0093 DWORD buffSize = 1024; 0094 char buffer[1024]; 0095 GET_CONFIGURATION_IOCTL_INPUT input; 0096 ZeroMemory(&input, sizeof(GET_CONFIGURATION_IOCTL_INPUT)); 0097 input.Feature = FeatureProfileList; 0098 input.RequestType = SCSI_GET_CONFIGURATION_REQUEST_TYPE_ALL; 0099 0100 WinDeviceManager::getDeviceInfo<char, GET_CONFIGURATION_IOCTL_INPUT>(drive, IOCTL_CDROM_GET_CONFIGURATION, buffer, buffSize, &input); 0101 0102 GET_CONFIGURATION_HEADER *info = (GET_CONFIGURATION_HEADER *)buffer; 0103 FEATURE_DATA_PROFILE_LIST *profile = (FEATURE_DATA_PROFILE_LIST *)info->Data; 0104 FEATURE_DATA_PROFILE_LIST_EX *feature = profile->Profiles; 0105 for (int i = 0; i < profile->Header.AdditionalLength / 4; ++feature, ++i) { 0106 MediaProfiles p = MediaProfiles(feature); 0107 if (!p.isNull()) { 0108 out.insert(p.profile, p); 0109 } 0110 } 0111 0112 return out; 0113 } 0114 0115 const MediaProfiles MediaProfiles::getProfile(ulong val) 0116 { 0117 #define AddProfile(profile, type) profiles.insert(profile, MediaProfiles(profile, type, #profile)) 0118 static QMap<ulong, MediaProfiles> profiles; 0119 if (profiles.isEmpty()) { 0120 AddProfile(ProfileCdrom, Solid::OpticalDrive::UnknownMediumType); 0121 AddProfile(ProfileCdRecordable, Solid::OpticalDrive::Cdr); 0122 AddProfile(ProfileCdRewritable, Solid::OpticalDrive::Cdrw); 0123 AddProfile(ProfileDvdRom, Solid::OpticalDrive::Dvd); 0124 AddProfile(ProfileDvdRecordable, Solid::OpticalDrive::Dvdr); 0125 AddProfile(ProfileDvdRewritable, Solid::OpticalDrive::Dvdrw); 0126 AddProfile(ProfileDvdRam, Solid::OpticalDrive::Dvdram); 0127 AddProfile(ProfileDvdPlusR, Solid::OpticalDrive::Dvdplusr); 0128 AddProfile(ProfileDvdPlusRW, Solid::OpticalDrive::Dvdplusrw); 0129 AddProfile(ProfileDvdPlusRDualLayer, Solid::OpticalDrive::Dvdplusdl); 0130 AddProfile(ProfileDvdPlusRWDualLayer, Solid::OpticalDrive::Dvdplusdlrw); 0131 AddProfile(ProfileBDRom, Solid::OpticalDrive::Bd); 0132 AddProfile(ProfileBDRRandomWritable, Solid::OpticalDrive::Bdr); 0133 AddProfile(ProfileBDRSequentialWritable, Solid::OpticalDrive::Bdr); 0134 AddProfile(ProfileBDRewritable, Solid::OpticalDrive::Bdre); 0135 AddProfile(ProfileHDDVDRom, Solid::OpticalDrive::HdDvd); 0136 AddProfile(ProfileHDDVDRecordable, Solid::OpticalDrive::HdDvdr); 0137 AddProfile(ProfileHDDVDRewritable, Solid::OpticalDrive::HdDvdrw); 0138 } 0139 return profiles[val]; 0140 } 0141 0142 #include "moc_winopticaldrive.cpp"