Initial merge of alpha quality HAL replacement backend for the media kioslave

Pass the WITH_TDEHWLIB CMake option to enable this backend
pull/2/head
Timothy Pearson 12 years ago
parent d4e6607ad6
commit 03d905ea26

@ -77,6 +77,7 @@ option( WITH_XINERAMA "Enable xinerama extension support" ${WITH_ALL_OPTIONS} )
option( WITH_ARTS "Enable aRts support" ${WITH_ALL_OPTIONS} )
option( WITH_I8K "Enable Dell laptop support (ksysguard)" ${WITH_ALL_OPTIONS} )
option( WITH_HAL "Enable HAL support" ${WITH_ALL_OPTIONS} )
option( WITH_TDEHWLIB "Enable TDE hardware library support" ${WITH_ALL_OPTIONS} )
option( WITH_UPOWER "Enable UPOWER support" ${WITH_ALL_OPTIONS} )
option( WITH_GCC_VISIBILITY "Enable fvisibility and fvisibility-inlines-hidden" ${WITH_ALL_OPTIONS} )

@ -31,6 +31,14 @@
#define COMPILE_LINUXCDPOLLING
#endif
// kioslave/media
#cmakedefine WITH_TDEHWLIB 1
#ifdef WITH_TDEHWLIB
// forcibly deactivate HAL support and substitute TDE hardware library support
#undef COMPILE_HALBACKEND
#define COMPILE_TDEHARDWAREBACKEND
#endif
// kioslave/fish, kcontrol/info
#cmakedefine HAVE_SYS_IOCTL_H 1

@ -23,6 +23,7 @@ tde_conditional_add_subdirectory( WITH_HAL propsdlgplugin )
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/libmediacommon
${CMAKE_BINARY_DIR}
${TDE_INCLUDE_DIR}
${TQT_INCLUDE_DIRS}
)

@ -9,6 +9,11 @@
<whatsthis>When HAL (Hardware Abstraction Layer) support is enabled, TDE will use it to gather information on the storage media available in your system.</whatsthis>
<default>true</default>
</entry>
<entry name="TdeHardwareBackendEnabled" type="Bool">
<label>Enable TDE hardware library backend</label>
<whatsthis>When TDE hardware library support is enabled, TDE will use it to gather information on the storage media available in your system.</whatsthis>
<default>true</default>
</entry>
<entry name="CdPollingEnabled" type="Bool">
<label>Enable CD polling</label>
<whatsthis>Allows TDE to poll CD-Rom or DVD-Rom drives itself in order to detect medium insert.</whatsthis>

@ -34,6 +34,8 @@
#include "medium.h"
#include <config.h>
MediaImpl::MediaImpl() : TQObject(), DCOPObject("mediaimpl"), mp_mounting(0L)
{
@ -226,13 +228,15 @@ bool MediaImpl::ensureMediumMounted(Medium &medium)
m_lastErrorMessage = i18n("No such medium.");
return false;
}
#ifdef COMPILE_HALBACKEND
if ( medium.isEncrypted() && medium.clearDeviceUdi().isEmpty() )
{
m_lastErrorCode = KIO::ERR_COULD_NOT_MOUNT;
m_lastErrorMessage = i18n("The drive is encrypted.");
return false;
}
#endif // COMPILE_HALBACKEND
if ( medium.needMounting() )
{

@ -9,9 +9,6 @@
#
#################################################
# FIXME there is no support for HAL and linuxcdpolling yet
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_BINARY_DIR}/kioslave/media/libmediacommon
@ -43,7 +40,8 @@ if( WITH_HAL )
mediamanager.cpp mediamanager.skel medialist.cpp
backendbase.cpp fstabbackend.cpp removablebackend.cpp
mediadirnotify.cpp mediadirnotify.skel
halbackend.cpp linuxcdpolling.cpp
decryptdialog.ui dialog.cpp
halbackend.cpp linuxcdpolling.cpp tdehardwarebackend.cpp
)
tde_add_kpart( ${target} AUTOMOC
@ -55,7 +53,8 @@ else( )
set( ${target}_SRCS
mediamanager.cpp mediamanager.skel medialist.cpp
backendbase.cpp fstabbackend.cpp removablebackend.cpp
mediadirnotify.cpp mediadirnotify.skel
decryptdialog.ui dialog.cpp
mediadirnotify.cpp mediadirnotify.skel tdehardwarebackend.cpp
)
tde_add_kpart( ${target} AUTOMOC

@ -0,0 +1,201 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>DecryptDialog</class>
<widget class="TQWidget">
<property name="name">
<cstring>DecryptDialog</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>207</width>
<height>172</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>5</hsizetype>
<vsizetype>3</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="caption">
<string>Decrypting Storage Device</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLayoutWidget" row="0" column="0">
<property name="name">
<cstring>layout5</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>layout4</cstring>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>encryptedIcon</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>0</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>AlignTop</set>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer2_2</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>31</width>
<height>41</height>
</size>
</property>
</spacer>
</vbox>
</widget>
<widget class="TQLabel">
<property name="name">
<cstring>descLabel</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>3</hsizetype>
<vsizetype>3</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;p&gt;&lt;b&gt;%1&lt;/b&gt; is an encrypted storage device.&lt;/p&gt;
&lt;p&gt;Please enter the password to decrypt the storage device.&lt;/p&gt;</string>
</property>
<property name="alignment">
<set>WordBreak|AlignTop</set>
</property>
</widget>
</hbox>
</widget>
<widget class="TQLayoutWidget" row="1" column="0">
<property name="name">
<cstring>layout4</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="text">
<string>&amp;Password:</string>
</property>
<property name="buddy" stdset="0">
<cstring>passwordEdit</cstring>
</property>
</widget>
<widget class="TQLineEdit">
<property name="name">
<cstring>passwordEdit</cstring>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>5</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="echoMode">
<enum>Password</enum>
</property>
</widget>
</hbox>
</widget>
<widget class="TQGroupBox" row="2" column="0">
<property name="name">
<cstring>errorBox</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>3</hsizetype>
<vsizetype>3</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Error</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel" row="0" column="0">
<property name="name">
<cstring>errorLabel</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>3</hsizetype>
<vsizetype>3</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string></string>
</property>
<property name="alignment">
<set>WordBreak|AlignTop</set>
</property>
</widget>
</grid>
</widget>
</grid>
</widget>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,68 @@
/* This file is part of the KDE project
* Copyright (C) 2007 Jan Klötzke <jan kloetzke at freenet de>
*
* Based on kryptomedia- Another KDE cryto media application.
* Copyright (C) 2006 Daniel Gollub <dgollub@suse.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "dialog.h"
Dialog::Dialog(TQString url, TQString iconName) :
KDialogBase(NULL, "Dialog", true, "Decrypt Storage Device", (Cancel|User1), User1, false, KGuiItem(i18n("Decrypt"), "decrypted" ))
{
decryptDialog = new DecryptDialog(this);
decryptDialog->errorBox->hide();
decryptDialog->descLabel->setText(decryptDialog->descLabel->text().arg(url));
decryptDialog->descLabel->adjustSize();
decryptDialog->adjustSize();
enableButton( User1, false );
TQPixmap pixmap = KGlobal::iconLoader()->loadIcon(iconName, KIcon::NoGroup, KIcon::SizeLarge);
decryptDialog->encryptedIcon->setPixmap( pixmap );
connect(decryptDialog->passwordEdit, TQT_SIGNAL (textChanged(const TQString &)), this, TQT_SLOT (slotPasswordChanged(const TQString &)));
setMainWidget(decryptDialog);
}
Dialog::~Dialog()
{
delete decryptDialog;
}
TQString Dialog::getPassword()
{
return decryptDialog->passwordEdit->text();
}
void Dialog::slotDialogError(TQString errorMsg)
{
kdDebug() << __func__ << "(" << errorMsg << " )" << endl;
decryptDialog->errorLabel->setText(TQString("<b>%1</b>").arg(errorMsg));
decryptDialog->errorBox->show();
}
void Dialog::slotPasswordChanged(const TQString &text)
{
enableButton( User1, !text.isEmpty() );
}
#include "dialog.moc"

@ -0,0 +1,61 @@
/* This file is part of the KDE project
* Copyright (C) 2007 Jan Klötzke <jan kloetzke at freenet de>
*
* Based on kryptomedia- Another KDE cryto media application.
* Copyright (C) 2006 Daniel Gollub <dgollub@suse.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef DIALOG_H_
#define DIALOG_H_
#include <kmessagebox.h>
#include <klocale.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kdialogbase.h>
#include <kiconloader.h>
#include <tqlineedit.h>
#include <tqlabel.h>
#include <tqgroupbox.h>
#include "decryptdialog.h"
class KryptoMedia;
class Dialog : public KDialogBase
{
Q_OBJECT
public:
Dialog(TQString url, TQString iconName);
~Dialog();
TQString getPassword();
public slots:
void slotDialogError(TQString errorMsg);
void slotPasswordChanged(const TQString &text);
private:
DecryptDialog *decryptDialog;
};
#endif // DIALOG_H_

@ -32,6 +32,10 @@
#include "fstabbackend.h"
#ifdef COMPILE_TDEHARDWAREBACKEND
#include "tdehardwarebackend.h"
#endif // COMPILE_TDEHARDWAREBACKEND
#ifdef COMPILE_HALBACKEND
#include "halbackend.h"
#endif //COMPILE_HALBACKEND
@ -78,6 +82,7 @@ void MediaManager::loadBackends()
mp_removableBackend = 0L;
m_halbackend = 0L;
m_tdebackend = 0L;
m_fstabbackend = 0L;
#ifdef COMPILE_HALBACKEND
@ -103,6 +108,20 @@ void MediaManager::loadBackends()
}
#endif // COMPILE_HALBACKEND
#ifdef COMPILE_TDEHARDWAREBACKEND
if ( MediaManagerSettings::self()->tdeHardwareBackendEnabled() )
{
m_mediaList.blockSignals(false);
m_tdebackend = new TDEBackend(m_mediaList, this);
m_backends.append( m_tdebackend );
m_fstabbackend = new FstabBackend(m_mediaList, true);
m_backends.append( m_fstabbackend );
// No need to load something else...
m_mediaList.blockSignals(false);
return;
}
#endif // COMPILE_TDEHARDWAREBACKEND
mp_removableBackend = new RemovableBackend(m_mediaList);
m_backends.append( mp_removableBackend );
@ -189,71 +208,107 @@ TQStringList MediaManager::properties(const TQString &name)
TQStringList MediaManager::mountoptions(const TQString &name)
{
#ifdef COMPILE_HALBACKEND
if (!m_halbackend)
return TQStringList();
return m_halbackend->mountoptions(name);
#else
return TQStringList();
#endif
if (!m_halbackend)
return TQStringList();
return m_halbackend->mountoptions(name);
#else // COMPILE_HALBACKEND
#ifdef COMPILE_TDEHARDWAREBACKEND
if (!m_tdebackend)
return TQStringList();
return m_tdebackend->mountoptions(name);
#else // COMPILE_TDEHARDWAREBACKEND
return TQStringList();
#endif // COMPILE_TDEHARDWAREBACKEND
#endif // COMPILE_HALBACKEND
}
bool MediaManager::setMountoptions(const TQString &name, const TQStringList &options)
{
#ifdef COMPILE_HALBACKEND
if (!m_halbackend)
return false;
return m_halbackend->setMountoptions(name, options);
#else
return false;
#endif
if (!m_halbackend)
return false;
return m_halbackend->setMountoptions(name, options);
#else // COMPILE_HALBACKEND
#ifdef COMPILE_TDEHARDWAREBACKEND
if (!m_tdebackend)
return false;
return m_tdebackend->setMountoptions(name, options);
#else // COMPILE_TDEHARDWAREBACKEND
return false;
#endif // COMPILE_TDEHARDWAREBACKEND
#endif // COMPILE_HALBACKEND
}
TQString MediaManager::mount(const TQString &name)
{
#ifdef COMPILE_HALBACKEND
if (!m_halbackend)
return i18n("Feature only available with HAL");
return m_halbackend->mount(name);
#else
if ( !m_fstabbackend ) // lying :)
return i18n("Feature only available with HAL");
return m_fstabbackend->mount( name );
#endif
if (!m_halbackend)
return i18n("Feature only available with HAL");
return m_halbackend->mount(name);
#else // COMPILE_HALBACKEND
#ifdef COMPILE_TDEHARDWAREBACKEND
if (!m_tdebackend)
return i18n("Feature only available with the TDE hardware backend");
return m_tdebackend->mount(name);
#else // COMPILE_TDEHARDWAREBACKEND
if ( !m_fstabbackend ) // lying :)
return i18n("Feature only available with HAL or TDE hardware backend");
return m_fstabbackend->mount( name );
#endif // COMPILE_TDEHARDWAREBACKEND
#endif // COMPILE_HALBACKEND
}
TQString MediaManager::unmount(const TQString &name)
{
#ifdef COMPILE_HALBACKEND
if (!m_halbackend)
return i18n("Feature only available with HAL");
return m_halbackend->unmount(name);
#else
if ( !m_fstabbackend ) // lying :)
return i18n("Feature only available with HAL");
return m_fstabbackend->unmount( name );
#endif
if (!m_halbackend)
return i18n("Feature only available with HAL");
return m_halbackend->unmount(name);
#else // COMPILE_HALBACKEND
#ifdef COMPILE_TDEHARDWAREBACKEND
if (!m_tdebackend)
return i18n("Feature only available with HAL or TDE hardware backend");
return m_tdebackend->unmount(name);
#else // COMPILE_TDEHARDWAREBACKEND
if ( !m_fstabbackend ) // lying :)
return i18n("Feature only available with HAL or TDE hardware backend");
return m_fstabbackend->unmount( name );
#endif // COMPILE_TDEHARDWAREBACKEND
#endif // COMPILE_HALBACKEND
}
TQString MediaManager::decrypt(const TQString &name, const TQString &password)
{
#ifdef COMPILE_HALBACKEND
if (!m_halbackend)
return i18n("Feature only available with HAL");
return m_halbackend->decrypt(name, password);
#else
return i18n("Feature only available with HAL");
#endif
if (!m_halbackend)
return i18n("Feature only available with HAL");
return m_halbackend->decrypt(name, password);
#else // COMPILE_HALBACKEND
// #ifdef COMPILE_TDEHARDWAREBACKEND
// if (!m_tdebackend)
// return i18n("Feature only available with HAL or TDE hardware backend");
// return m_tdebackend->decrypt(name, password);
// #else // COMPILE_TDEHARDWAREBACKEND
return i18n("Feature only available with HAL");
// #endif // COMPILE_TDEHARDWAREBACKEND
#endif // COMPILE_HALBACKEND
}
TQString MediaManager::undecrypt(const TQString &name)
{
#ifdef COMPILE_HALBACKEND
if (!m_halbackend)
return i18n("Feature only available with HAL");
return m_halbackend->undecrypt(name);
#else
return i18n("Feature only available with HAL");
#endif
if (!m_halbackend)
return i18n("Feature only available with HAL");
return m_halbackend->undecrypt(name);
#else // COMPILE_HALBACKEND
// #ifdef COMPILE_TDEHARDWAREBACKEND
// if (!m_tdebackend)
// return i18n("Feature only available with HAL or TDE hardware backend");
// return m_tdebackend->undecrypt(name);
// #else // COMPILE_TDEHARDWAREBACKEND
return i18n("Feature only available with HAL");
// #endif // COMPILE_TDEHARDWAREBACKEND
#endif // COMPILE_HALBACKEND
}
TQString MediaManager::nameForLabel(const TQString &label)

@ -1,5 +1,5 @@
/* This file is part of the KDE Project
Copyright (c) 2004 Kévin Ottens <ervin ipsquad net>
Copyright (c) 2004 K<EFBFBD>vin Ottens <ervin ipsquad net>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@ -29,6 +29,7 @@
#include "mediadirnotify.h"
class HALBackend;
class TDEBackend;
class FstabBackend;
class MediaManager : public KDEDModule
@ -85,6 +86,7 @@ private:
TQValueList<BackendBase*> m_backends;
RemovableBackend *mp_removableBackend;
HALBackend *m_halbackend;
TDEBackend *m_tdebackend;
MediaDirNotify m_dirNotify;
FstabBackend *m_fstabbackend;
};

@ -0,0 +1,924 @@
/* This file is part of the TDE Project
Copyright (c) 2012 Timothy Pearson <kb9vqf@pearsoncomputing.net>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "tdehardwarebackend.h"
#include <tqfile.h>
#include <tqeventloop.h>
#include <tqstylesheet.h>
#include <kglobal.h>
#include <klocale.h>
#include <kconfig.h>
#include <kio/job.h>
#include <kprocess.h>
#include <kmimetype.h>
#include <kmountpoint.h>
#include <kmessagebox.h>
#include <kapplication.h>
#include <kprotocolinfo.h>
#include "dialog.h"
#define MOUNT_SUFFIX ( \
(medium->isMounted() ? TQString("_mounted") : TQString("_unmounted")) + \
(medium->isEncrypted() ? (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt) ? "_decrypted" : "_encrypted") : "" ) \
)
#define MOUNT_ICON_SUFFIX ( \
(medium->isMounted() ? TQString("_mount") : TQString("_unmount")) + \
(medium->isEncrypted() ? (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt) ? "_decrypt" : "_encrypt") : "" ) \
)
/* Constructor */
TDEBackend::TDEBackend(MediaList &list, TQObject* parent)
: TQObject()
, BackendBase(list)
, m_decryptDialog(0)
, m_parent(parent)
{
// Initialize the TDE device manager
TDEHardwareDevices *hwdevices = KGlobal::hardwareDevices();
// Connect device monitoring signals/slots
connect(hwdevices, TQT_SIGNAL(hardwareAdded(TDEGenericDevice*)), this, TQT_SLOT(AddDeviceHandler(TDEGenericDevice*)));
connect(hwdevices, TQT_SIGNAL(hardwareRemoved(TDEGenericDevice*)), this, TQT_SLOT(RemoveDeviceHandler(TDEGenericDevice*)));
connect(hwdevices, TQT_SIGNAL(hardwareUpdated(TDEGenericDevice*)), this, TQT_SLOT(ModifyDeviceHandler(TDEGenericDevice*)));
// List devices at startup
ListDevices();
}
/* Destructor */
TDEBackend::~TDEBackend()
{
// Remove all media from the media list
TDEHardwareDevices *hwdevices = KGlobal::hardwareDevices();
TDEGenericHardwareList hwlist = hwdevices->listAllPhysicalDevices();
TDEGenericDevice *hwdevice;
for ( hwdevice = hwlist.first(); hwdevice; hwdevice = hwlist.next() ) {
if (hwdevice->type() == TDEGenericDeviceType::Disk) {
TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
RemoveDevice(sdevice);
}
}
}
void TDEBackend::AddDeviceHandler(TDEGenericDevice *device) {
if (device->type() == TDEGenericDeviceType::Disk) {
TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
AddDevice(sdevice);
}
}
void TDEBackend::RemoveDeviceHandler(TDEGenericDevice *device) {
if (device->type() == TDEGenericDeviceType::Disk) {
TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
RemoveDevice(sdevice);
}
}
void TDEBackend::ModifyDeviceHandler(TDEGenericDevice *device) {
if (device->type() == TDEGenericDeviceType::Disk) {
TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
ModifyDevice(sdevice);
}
}
// List devices (at startup)
bool TDEBackend::ListDevices()
{
TDEHardwareDevices *hwdevices = KGlobal::hardwareDevices();
TDEGenericHardwareList hwlist = hwdevices->listAllPhysicalDevices();
TDEGenericDevice *hwdevice;
for ( hwdevice = hwlist.first(); hwdevice; hwdevice = hwlist.next() ) {
if (hwdevice->type() == TDEGenericDeviceType::Disk) {
TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
AddDevice(sdevice, false);
}
}
return true;
}
// Create a media instance for a new storage device
void TDEBackend::AddDevice(TDEStorageDevice * sdevice, bool allowNotification)
{
// If the device is already listed, do not process it
// This should not happen, but who knows...
/** @todo : refresh properties instead ? */
if (m_mediaList.findById(sdevice->uniqueID())) {
return;
}
// Add volume block devices
if (sdevice->isDiskOfType(TDEDiskDeviceType::HDD)) {
/* We only list volumes that...
* - are encrypted with LUKS or
* - have a filesystem or
* - have an audio track
*/
if (!(sdevice->isDiskOfType(TDEDiskDeviceType::LUKS))
&& !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem))
&& !(sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio))
&& !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank))
) {
//
}
else {
// Do not list the LUKS backend device if it has been unlocked elsewhere
if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) {
if (sdevice->slaveDevices().count() > 0) {
return;
}
}
// Create medium
Medium* medium = new Medium(sdevice->uniqueID(), "");
setVolumeProperties(medium);
// Insert medium into list
m_mediaList.addMedium(medium, allowNotification);
}
}
// Add CD drives
if ((sdevice->isDiskOfType(TDEDiskDeviceType::CDROM))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::CDRW))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::BDROM))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::BDRW))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo))
) {
// Create medium
Medium* medium = new Medium(sdevice->uniqueID(), "");
setVolumeProperties(medium);
// Insert medium into list
m_mediaList.addMedium(medium, allowNotification);
}
// Floppy & zip drives
if ((sdevice->isDiskOfType(TDEDiskDeviceType::Floppy)) ||
(sdevice->isDiskOfType(TDEDiskDeviceType::Zip)) ||
(sdevice->isDiskOfType(TDEDiskDeviceType::Jaz))
) {
if ((sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable)) && (!(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Inserted)))) {
allowNotification = false;
}
// Create medium
Medium* medium = new Medium(sdevice->uniqueID(), "");
// If the storage has a volume, we ignore it
if ( setFloppyProperties(medium) )
m_mediaList.addMedium(medium, allowNotification);
else
delete medium;
return;
}
// PTP camera
if (sdevice->isDiskOfType(TDEDiskDeviceType::Camera)) {
// PTP cameras are handled by the "camera" kioslave
if (KProtocolInfo::isKnownProtocol( TQString("camera") ) )
{
// Create medium
Medium* medium = new Medium(sdevice->uniqueID(), "");
setCameraProperties(medium);
m_mediaList.addMedium(medium, allowNotification);
return;
}
}
}
void TDEBackend::RemoveDevice(TDEStorageDevice * sdevice)
{
const Medium *medium = m_mediaList.findByClearUdi(sdevice->uniqueID());
if (medium) {
ResetProperties(sdevice);
}
else {
m_mediaList.removeMedium(sdevice->uniqueID(), true);
}
}
void TDEBackend::ModifyDevice(TDEStorageDevice * sdevice)
{
bool allowNotification = true;
if (!sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable)) { // TODO Is this the only condition under which we would not want notification?
allowNotification = false;
}
ResetProperties(sdevice, allowNotification);
}
void TDEBackend::ResetProperties(TDEStorageDevice * sdevice, bool allowNotification)
{
Medium* m = new Medium(sdevice->uniqueID(), "");
// Keep these conditions in sync with ::AddDevice above, OR ELSE!!!
// BEGIN
if (!(sdevice->isDiskOfType(TDEDiskDeviceType::LUKS))
&& !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem))
&& !(sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio))
&& !(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank))
) {
}
else {
if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) {
if (sdevice->slaveDevices().count() > 0) {
// Do not list the LUKS backend device if it has been unlocked elsewhere
RemoveDevice(sdevice);
return;
}
}
setVolumeProperties(m);
}
if ((sdevice->isDiskOfType(TDEDiskDeviceType::CDROM))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::CDRW))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::BDROM))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::BDRW))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo))
) {
setVolumeProperties(m);
}
// Floppy & zip drives
if ((sdevice->isDiskOfType(TDEDiskDeviceType::Floppy)) ||
(sdevice->isDiskOfType(TDEDiskDeviceType::Zip)) ||
(sdevice->isDiskOfType(TDEDiskDeviceType::Jaz))
) {
setFloppyProperties(m);
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::Camera)) {
setCameraProperties(m);
}
// END
m_mediaList.changeMediumState(*m, allowNotification);
delete m;
}
void TDEBackend::setVolumeProperties(Medium* medium)
{
TDEHardwareDevices *hwdevices = KGlobal::hardwareDevices();
TDEStorageDevice * sdevice = hwdevices->findDiskByUID(medium->id());
if (!sdevice) {
return;
}
medium->setName(generateName(sdevice->deviceNode()));
if ((sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) || (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt))) {
medium->setEncrypted(true);
}
else {
medium->setEncrypted(false);
}
// USAGE: mountableState(Device node, Mount point, Filesystem type, Mounted ?)
medium->mountableState(sdevice->deviceNode(), sdevice->mountPath(), sdevice->fileSystemName(), !sdevice->mountPath().isNull());
TQString diskLabel = sdevice->diskLabel();
if (diskLabel.isNull()) {
diskLabel = i18n("%1 Removable Device").arg(sdevice->deviceFriendlySize());
}
medium->setLabel(diskLabel);
TQString mimeType;
if ((sdevice->isDiskOfType(TDEDiskDeviceType::CDROM))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::CDRW))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::BDROM))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::BDRW))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo))
|| (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo))
) {
// This device is a CD drive of some sort
// Default
mimeType = "media/cdrom" + MOUNT_SUFFIX;
if (sdevice->isDiskOfType(TDEDiskDeviceType::CDROM)) {
mimeType = "media/cdrom" + MOUNT_SUFFIX;
if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) {
mimeType = "media/blankcd" + MOUNT_SUFFIX;
medium->unmountableState("");
}
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::CDRW)) {
mimeType = "media/cdwriter" + MOUNT_SUFFIX;
if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) {
mimeType = "media/blankcd" + MOUNT_SUFFIX;
medium->unmountableState("");
}
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM)) {
mimeType = "media/dvd" + MOUNT_SUFFIX;
if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) {
mimeType = "media/blankdvd" + MOUNT_SUFFIX;
medium->unmountableState("");
}
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM)) {
mimeType = "media/dvd" + MOUNT_SUFFIX;
if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) {
mimeType = "media/blankdvd" + MOUNT_SUFFIX;
medium->unmountableState("");
}
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW)) {
mimeType = "media/dvd" + MOUNT_SUFFIX;
if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) {
mimeType = "media/blankdvd" + MOUNT_SUFFIX;
medium->unmountableState("");
}
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::BDROM)) {
mimeType = "media/bluray" + MOUNT_SUFFIX;
if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) {
mimeType = "media/blankbd" + MOUNT_SUFFIX;
medium->unmountableState("");
}
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::BDRW)) {
mimeType = "media/bluray" + MOUNT_SUFFIX;
if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) {
mimeType = "media/blankbd" + MOUNT_SUFFIX;
medium->unmountableState("");
}
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio)) {
mimeType = "media/audiocd" + MOUNT_SUFFIX;
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo)) {
mimeType = "media/vcd";
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo)) {
mimeType = "media/dvdvideo";
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo)) {
mimeType = "media/bdvideo";
}
medium->setIconName(TQString::null);
}
else {
// This device is a hard or flash disk of some kind
// Default
mimeType = "media/hdd" + MOUNT_SUFFIX;
if (sdevice->isDiskOfType(TDEDiskDeviceType::USB)) {
mimeType = "media/removable" + MOUNT_SUFFIX;
medium->needMounting();
if (sdevice->isDiskOfType(TDEDiskDeviceType::CompactFlash)) {
medium->setIconName("compact_flash" + MOUNT_ICON_SUFFIX);
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::CompactFlash)) {
medium->setIconName("memory_stick" + MOUNT_ICON_SUFFIX);
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::CompactFlash)) {
medium->setIconName("smart_media" + MOUNT_ICON_SUFFIX);
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::CompactFlash)) {
medium->setIconName("sd_mmc" + MOUNT_ICON_SUFFIX);
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::MediaDevice)) {
medium->setIconName("ipod" + MOUNT_ICON_SUFFIX);
if (sdevice->vendorModel().upper().contains("IPOD") && KProtocolInfo::isKnownProtocol( TQString("ipod") ) )
{
medium->unmountableState( "ipod:/" );
medium->mountableState(!sdevice->mountPath().isNull());
}
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::Tape)) {
medium->setIconName("magnetic_tape" + MOUNT_ICON_SUFFIX);
}
if (medium->isMounted() && TQFile::exists(medium->mountPoint() + "/dcim"))
{
mimeType = "media/camera" + MOUNT_SUFFIX;
}
}
}
medium->setMimeType(mimeType);
}
// Handle floppies and zip drives
bool TDEBackend::setFloppyProperties(Medium* medium)
{
TDEHardwareDevices *hwdevices = KGlobal::hardwareDevices();
TDEStorageDevice * sdevice = hwdevices->findDiskByUID(medium->id());
if (!sdevice) {
return false;
}
medium->setName(generateName(sdevice->deviceNode()));
medium->setLabel(i18n("Unknown Drive"));
if (sdevice->isDiskOfType(TDEDiskDeviceType::Floppy)) {
if (sdevice->mountPath().isNull()) {
medium->setMimeType("media/floppy_unmounted");
}
else {
medium->setMimeType("media/floppy_mounted" );
}
medium->setLabel(i18n("Floppy Drive"));
}
if (sdevice->isDiskOfType(TDEDiskDeviceType::Zip)) {
if (sdevice->mountPath().isNull()) {
medium->setMimeType("media/zip_unmounted");
}
else {
medium->setMimeType("media/zip_mounted" );
}
medium->setLabel(i18n("Zip Drive"));
}
/** @todo Mimetype for JAZ drives ? */
medium->setIconName(TQString::null);
return true;
}
void TDEBackend::setCameraProperties(Medium* medium)
{
TDEHardwareDevices *hwdevices = KGlobal::hardwareDevices();
TDEStorageDevice * sdevice = hwdevices->findDiskByUID(medium->id());
if (!sdevice) {
return;
}
/** @todo find name */
medium->setName("camera");
TQString device = "camera:/";
// FIXME
// I don't have a PTP camera to develop with
// Getting this working should be fairly easy; you just have to query udev for this information via the /sys/... path returned by sdevice->systemPath()
// if () {
// device.sprintf("camera://%s@[usb:%03d,%03d]/", <camera's libgphoto2 name>, <usb bus number>, <usb linux device number>);
// }
/** @todo find the rest of this URL */
medium->unmountableState(device);
medium->setMimeType("media/gphoto2camera");
medium->setIconName(TQString::null);
if (sdevice->vendorModel() != "") {
medium->setLabel(sdevice->vendorModel());
}
else {
medium->setLabel(i18n("Camera"));
}
}
TQStringList TDEBackend::mountoptions(const TQString &name)
{
const Medium* medium = m_mediaList.findById(name);
if (!medium) {
return TQStringList(); // we know nothing about that device
}
if (!isInFstab(medium).isNull()) {
return TQStringList(); // device is listed in fstab, therefore is not handled by us
}
TQString volume_udi = name;
if (medium->isEncrypted()) {
// if not decrypted yet then there are no mountoptions
return TQStringList();
}
// FIXME
// Just use the default mount options for now
return TQStringList();
}
bool TDEBackend::setMountoptions(const TQString &name, const TQStringList &options )
{
// FIXME
// Just use the default mount options for now
return true;
}
void TDEBackend::slotPasswordReady() {
m_decryptionPassword = m_decryptDialog->getPassword();
m_decryptPasswordValid = true;
}
void TDEBackend::slotPasswordCancel() {
m_decryptionPassword = TQString::null;
m_decryptPasswordValid = true;
}
TQString TDEBackend::mount(const Medium *medium)
{
if (medium->isMounted()) {
return TQString(); // that was easy
}
TQString mountPoint = isInFstab(medium);
if (!mountPoint.isNull())
{
struct mount_job_data data;
data.completed = false;
data.medium = medium;
KIO::Job *job = KIO::mount( false, 0, medium->deviceNode(), mountPoint );
connect(job, TQT_SIGNAL( result (KIO::Job *)), TQT_SLOT( slotResult( KIO::Job *)));
mount_jobs[job] = &data;
// The caller expects the device to be mounted when the function
// completes. Thus block until the job completes.
while (!data.completed) {
kapp->eventLoop()->enterLoop();
}
// Return the error message (if any) to the caller
return (data.error) ? data.errorMessage : TQString::null;
}
TDEHardwareDevices *hwdevices = KGlobal::hardwareDevices();
TDEStorageDevice * sdevice = hwdevices->findDiskByUID(medium->id());
if (!sdevice) {
return i18n("Internal error");
}
TQString optionString;
TQString diskLabel;
TQMap<TQString,TQString> valids = MediaManagerUtils::splitOptions(mountoptions(medium->id()));
if (valids["ro"] == "true") {
optionString.append(" -r");
}
if (valids["atime"] != "true") {
optionString.append(" -A");
}
if (valids["utf8"] == "true") {
optionString.append(" -c utf8");
}
if (valids["sync"] == "true") {
optionString.append(" -s");
}
TQString mount_point = valids["mountpoint"];
if (mount_point.startsWith("/media/")) {
mount_point = mount_point.mid(7);
}
if (valids.contains("shortname")) {
diskLabel = TQString("shortname=%1").arg(valids["shortname"]);
}
TQString qerror = i18n("Cannot mount encrypted drives!");
if (!medium->isEncrypted()) {
// normal volume
TQString mountMessages;
TQString mountedPath = sdevice->mountDevice(diskLabel, optionString, &mountMessages);
if (mountedPath.isNull()) {
qerror = i18n("<qt>Unable to mount this device.<p>Potential reasons include:<br>Improper device and/or user privilege level<br>Corrupt data on storage device");
if (!mountMessages.isNull()) {
qerror.append(i18n("<p>Technical details:<br>").append(mountMessages));
}
qerror.append("</qt>");
}
else {
qerror = "";
}
}
else {
TQString iconName = medium->iconName();
if (iconName.isEmpty())
{
TQString mime = medium->mimeType();
iconName = KMimeType::mimeType(mime)->icon(mime, false);
}
bool continue_trying_to_decrypt = true;
while (continue_trying_to_decrypt == true) {
m_decryptPasswordValid = false;
m_decryptDialog = new Dialog(sdevice->deviceNode(), iconName);
m_decryptDialog->show();
connect(m_decryptDialog, TQT_SIGNAL (user1Clicked()), this, TQT_SLOT (slotPasswordReady()));
connect(m_decryptDialog, TQT_SIGNAL (cancelClicked()), this, TQT_SLOT (slotPasswordCancel()));
connect(this, TQT_SIGNAL (signalDecryptionPasswordError(TQString)), m_decryptDialog, TQT_SLOT (slotDialogError(TQString)));
while (m_decryptPasswordValid == false) {
tqApp->processEvents();
}
m_decryptDialog->setEnabled(false);
if (m_decryptionPassword.isNull()) {
delete m_decryptDialog;
return TQString("Decryption aborted");
}
else {
// mount encrypted volume with password
int mountRetcode;
TQString mountMessages;
TQString mountedPath = sdevice->mountEncryptedDevice(m_decryptionPassword, diskLabel, optionString, &mountMessages, &mountRetcode);
if (mountedPath.isNull()) {
if (mountRetcode == 25600) {
// Probable LUKS failure
// Retry
m_decryptDialog->setEnabled(true);
continue_trying_to_decrypt = true;
}
else {
qerror = i18n("<qt>Unable to mount this device.<p>Potential reasons include:<br>Improper device and/or user privilege level<br>Corrupt data on storage device<br>Incorrect encryption password");
if (!mountMessages.isNull()) {
qerror.append(i18n("<p>Technical details:<br>").append(mountMessages));
}
qerror.append("</qt>");
continue_trying_to_decrypt = false;
}
}
else {
qerror = "";
continue_trying_to_decrypt = false;
}
delete m_decryptDialog;
}
}
}
// FIXME
// Handle encrypted devices
// qerror = mount_priv(medium->id().latin1(), mount_point.utf8(), options, noptions, dbus_connection);
// } else {
// // see if we have a clear volume
// LibHalVolume* halVolume = libhal_volume_from_udi(m_halContext, medium->id().latin1());
// if (halVolume) {
// char* clearUdi = libhal_volume_crypto_get_clear_volume_udi(m_halContext, halVolume);
// if (clearUdi != NULL) {
// qerror = mount_priv(clearUdi, mount_point.utf8(), options, noptions, dbus_connection);
// libhal_free_string(clearUdi);
// }
// libhal_volume_free(halVolume);
// }
// }
if (!qerror.isEmpty()) {
return qerror;
}
ResetProperties(sdevice);
return TQString();
}
TQString TDEBackend::mount(const TQString &_udi)
{
const Medium* medium = m_mediaList.findById(_udi);
if (!medium)
return i18n("No such medium: %1").arg(_udi);
return mount(medium);
}
TQString TDEBackend::unmount(const TQString &_udi)
{
const Medium* medium = m_mediaList.findById(_udi);
if ( !medium )
return i18n("No such medium: %1").arg(_udi);
if (!medium->isMounted())
return TQString(); // that was easy
TQString mountPoint = isInFstab(medium);
if (!mountPoint.isNull())
{
struct mount_job_data data;
data.completed = false;
data.medium = medium;
KIO::Job *job = KIO::unmount( medium->mountPoint(), false );
connect(job, TQT_SIGNAL( result (KIO::Job *)), TQT_SLOT( slotResult( KIO::Job *)));
mount_jobs[job] = &data;
// The caller expects the device to be unmounted when the function
// completes. Thus block until the job completes.
while (!data.completed) {
kapp->eventLoop()->enterLoop();
}
// Return the error message (if any) to the caller
return (data.error) ? data.errorMessage : TQString::null;
}
TQString udi = TQString::null;
TDEHardwareDevices *hwdevices = KGlobal::hardwareDevices();
TDEStorageDevice * sdevice = hwdevices->findDiskByUID(medium->id());
if (!sdevice) {
return i18n("Internal error");
}
TQString qerror;
TQString origqerror;
TQString unmountMessages;
int unmountRetcode = 0;
if (!sdevice->unmountDevice(&unmountMessages, &unmountRetcode)) {
// Unmount failed!
qerror = "<qt>" + i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and currently mounted at <b>%4</b> could not be unmounted. ").arg("system:/media/" + medium->name(), medium->deviceNode(), medium->prettyLabel(), medium->prettyBaseURL().pathOrURL());
if (!unmountMessages.isNull()) {
qerror.append(i18n("<p>Technical details:<br>").append(unmountMessages));
}
qerror.append("</qt>");
}
else {
qerror = "";
}
if (unmountRetcode == 1280) {
// Failed as BUSY
TQString processesUsingDev = listUsingProcesses(medium);
if (!processesUsingDev.isNull()) {
if (KMessageBox::warningYesNo(0, i18n("<qt>The device <b>%1</b> (%2) named <b>'%3'</b> and currently mounted at <b>%4</b> can not be unmounted at this time.<p>%5<p><b>Would you like to forcibly terminate these processes?</b><br><i>All unsaved data would be lost</i>").arg("system:/media/" + medium->name()).arg(medium->deviceNode()).arg(medium->prettyLabel()).arg(medium->prettyBaseURL().pathOrURL()).arg(processesUsingDev)) == KMessageBox::Yes) {
killUsingProcesses(medium);
if (!sdevice->unmountDevice(&unmountMessages, &unmountRetcode)) {
// Unmount failed!
qerror = "<qt>" + i18n("Unfortunately, the device <b>%1</b> (%2) named <b>'%3'</b> and currently mounted at <b>%4</b> could not be unmounted. ").arg("system:/media/" + medium->name(), medium->deviceNode(), medium->prettyLabel(), medium->prettyBaseURL().pathOrURL());
if (!unmountMessages.isNull()) {
qerror.append(i18n("<p>Technical details:<br>").append(unmountMessages));
}
qerror.append("</qt>");
}
else {
qerror = "";
}
}
}
}
if (qerror != "") {
return qerror;
}
ResetProperties(sdevice);
return TQString();
}
TQString TDEBackend::isInFstab(const Medium *medium)
{
KMountPoint::List fstab = KMountPoint::possibleMountPoints(KMountPoint::NeedMountOptions|KMountPoint::NeedRealDeviceName);
KMountPoint::List::iterator it = fstab.begin();
KMountPoint::List::iterator end = fstab.end();
for (; it!=end; ++it)
{
TQString reald = (*it)->realDeviceName();
if ( reald.endsWith( "/" ) ) {
reald = reald.left( reald.length() - 1 );
}
if ((*it)->mountedFrom() == medium->deviceNode() || ( !medium->deviceNode().isEmpty() && reald == medium->deviceNode() ) )
{
TQStringList opts = (*it)->mountOptions();
if (opts.contains("user") || opts.contains("users")) {
return (*it)->mountPoint();
}
}
}
return TQString::null;
}
TQString TDEBackend::listUsingProcesses(const Medium* medium)
{
TQString proclist, fullmsg;
TQString cmdline = TQString("/usr/bin/env fuser -vm %1 2>&1").arg(KProcess::quote(medium->mountPoint()));
FILE *fuser = popen(cmdline.latin1(), "r");
uint counter = 0;
if (fuser) {
proclist += "<pre>";
TQTextIStream is(fuser);
TQString tmp;
while (!is.atEnd()) {
tmp = is.readLine();
tmp = TQStyleSheet::escape(tmp) + "\n";
proclist += tmp;
if (counter++ > 10) {
proclist += "...";
break;
}
}
proclist += "</pre>";
(void)pclose( fuser );
}
if (counter) {
fullmsg = i18n("Programs still using the device "
"have been detected. They are listed below. You have to "
"close them or change their working directory before "
"attempting to unmount the device again.");
fullmsg += "<br>" + proclist;
return fullmsg;
}
else {
return TQString::null;
}
}
TQString TDEBackend::killUsingProcesses(const Medium* medium)
{
TQString proclist, fullmsg;
TQString cmdline = TQString("/usr/bin/env fuser -vmk %1 2>&1").arg(KProcess::quote(medium->mountPoint()));
FILE *fuser = popen(cmdline.latin1(), "r");
uint counter = 0;
if (fuser) {
proclist += "<pre>";
TQTextIStream is(fuser);
TQString tmp;
while (!is.atEnd()) {
tmp = is.readLine();
tmp = TQStyleSheet::escape(tmp) + "\n";
proclist += tmp;
if (counter++ > 10) {
proclist += "...";
break;
}
}
proclist += "</pre>";
(void)pclose( fuser );
}
if (counter) {
fullmsg = i18n("Programs that were still using the device "
"have been forcibly terminated. They are listed below.");
fullmsg += "<br>" + proclist;
return fullmsg;
}
else {
return TQString::null;
}
}
TQString TDEBackend::generateName(const TQString &devNode)
{
return KURL(devNode).fileName();
}
#include "tdehardwarebackend.moc"

@ -0,0 +1,165 @@
/* This file is part of the TDE Project
Copyright (c) 2012 Timothy Pearson <kb9vqf@pearsoncomputing.net>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
/**
* This is a media:/ backend for the builtin TDE hardware library
*
* @author Timothy Pearson <kb9vqf@pearsoncomputing.net>
* @short media:/ backend for the TDE hardware library
*/
#ifndef _TDEBACKEND_H_
#define _TDEBACKEND_H_
#include "backendbase.h"
#include <tqobject.h>
#include <tqstringlist.h>
#include <tqstring.h>
#include <config.h>
#include <tdehardwaredevices.h>
namespace KIO {
class Job;
}
class Dialog;
class TDEBackend : public TQObject, public BackendBase
{
Q_OBJECT
public:
/**
* Constructor
*/
TDEBackend(MediaList &list, TQObject* parent);
/**
* Destructor
*/
~TDEBackend();
/**
* List all devices and append them to the media device list (called only once, at startup).
*
* @return true if succeded, false otherwise
*/
bool ListDevices();
TQStringList mountoptions(const TQString &id);
bool setMountoptions(const TQString &id, const TQStringList &options);
TQString mount(const TQString &id);
TQString mount(const Medium *medium);
TQString unmount(const TQString &id);
// TQString decrypt(const TQString &id, const TQString &password);
// TQString undecrypt(const TQString &id);
private:
/**
* Append a device in the media list. This function will check if the device
* is worth listing.
*
* @param sdevice A pointer to a TDEStorageDevice object
* @param allowNotification Indicates if this event will be notified to the user
*/
void AddDevice(TDEStorageDevice * sdevice, bool allowNotification=true);
/**
* Remove a device from the device list
*
* @param sdevice A pointer to a TDEStorageDevice object
*/
void RemoveDevice(TDEStorageDevice * sdevice);
/**
* A device has changed, update it
*
* @param sdevice A pointer to a TDEStorageDevice object
*/
void ModifyDevice(TDEStorageDevice * sdevice);
private slots:
void AddDeviceHandler(TDEGenericDevice* device);
void RemoveDeviceHandler(TDEGenericDevice* device);
void ModifyDeviceHandler(TDEGenericDevice* device);
void slotPasswordReady();
void slotPasswordCancel();
signals:
void signalDecryptionPasswordError(TQString);
/* Set media properties */
private:
/**
* Reset properties for the given medium
*
* @param sdevice A pointer to a TDEStorageDevice objec
*/
void ResetProperties(TDEStorageDevice * sdevice, bool allowNotification=false);
/**
* Find the medium that is concerned with device udi
*/
// const char* findMediumUdiFromUdi(const char* udi);
void setVolumeProperties(Medium* medium);
bool setFloppyProperties(Medium* medium);
// void setFloppyMountState( Medium* medium );
// bool setFstabProperties(Medium* medium);
void setCameraProperties(Medium* medium);
TQString generateName(const TQString &devNode);
static TQString isInFstab(const Medium *medium);
static TQString listUsingProcesses(const Medium *medium);
static TQString killUsingProcesses(const Medium *medium);
// Decryption
Dialog* m_decryptDialog;
TQString m_decryptionPassword;
bool m_decryptPasswordValid;
/* TDE structures */
private:
/**
* Object for the kded module
*/
TQObject* m_parent;
/**
* Data structure for fstab mount/unmount jobs
*/
struct mount_job_data {
// [in] Medium, which is being mounted/unmounted by the job
const Medium* medium;
// [in,out] Should be set to true when the job completes
bool completed;
// [out] KIO::Error if an error occured during operation. Otherwise, 0
int error;
// [out] Error message to be displayed to the user
TQString errorMessage;
};
TQMap<KIO::Job *, struct mount_job_data*> mount_jobs;
};
#endif /* _TDEBACKEND_H_ */
Loading…
Cancel
Save