1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2007 by Dominik Wenger
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "autodetection.h"
22 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
27 #if defined(Q_OS_WIN32)
37 Autodetection::Autodetection(QObject
* parent
): QObject(parent
)
42 bool Autodetection::detect()
50 // Try detection via rockbox.info / rbutil.log
51 QStringList mountpoints
= getMountpoints();
53 for(int i
=0; i
< mountpoints
.size();i
++)
55 // do the file checking
56 QDir
dir(mountpoints
.at(i
));
59 // check logfile first.
60 if(QFile(mountpoints
.at(i
) + "/.rockbox/rbutil.log").exists()) {
61 QSettings
log(mountpoints
.at(i
) + "/.rockbox/rbutil.log",
62 QSettings::IniFormat
, this);
63 if(!log
.value("platform").toString().isEmpty()) {
64 if(m_device
.isEmpty())
65 m_device
= log
.value("platform").toString();
66 m_mountpoint
= mountpoints
.at(i
);
67 qDebug() << "rbutil.log detected:" << m_device
<< m_mountpoint
;
72 // check rockbox-info.txt afterwards.
73 QFile
file(mountpoints
.at(i
) + "/.rockbox/rockbox-info.txt");
76 file
.open(QIODevice::ReadOnly
| QIODevice::Text
);
77 QString line
= file
.readLine();
78 if(line
.startsWith("Target: "))
80 line
.remove("Target: ");
81 if(m_device
.isEmpty())
82 m_device
= line
.trimmed(); // trim whitespaces
83 m_mountpoint
= mountpoints
.at(i
);
84 qDebug() << "rockbox-info.txt detected:" << m_device
<< m_mountpoint
;
88 // check for some specific files in root folder
89 QDir
root(mountpoints
.at(i
));
90 QStringList rootentries
= root
.entryList(QDir::Files
);
91 if(rootentries
.contains("archos.mod", Qt::CaseInsensitive
))
93 // archos.mod in root folder -> Archos Player
95 m_mountpoint
= mountpoints
.at(i
);
98 if(rootentries
.contains("ONDIOST.BIN"), Qt::CaseInsensitive
)
100 // ONDIOST.BIN in root -> Ondio FM
101 m_device
= "ondiofm";
102 m_mountpoint
= mountpoints
.at(i
);
105 if(rootentries
.contains("ONDIOSP.BIN"), Qt::CaseInsensitive
)
107 // ONDIOSP.BIN in root -> Ondio SP
108 m_device
= "ondiosp";
109 m_mountpoint
= mountpoints
.at(i
);
112 if(rootentries
.contains("ajbrec.ajz"), Qt::CaseInsensitive
)
114 qDebug() << "it's an archos. further detection needed";
116 // detection based on player specific folders
117 QStringList rootfolders
= root
.entryList(QDir::Dirs
| QDir::NoDotAndDotDot
);
118 if(rootfolders
.contains("GBSYSTEM"), Qt::CaseInsensitive
)
120 // GBSYSTEM folder -> Gigabeat
121 m_device
= "gigabeatf";
122 m_mountpoint
= mountpoints
.at(i
);
125 qDebug() << rootfolders
;
133 n
= ipod_scan(&ipod
);
135 qDebug() << "Ipod found:" << ipod
.modelstr
<< "at" << ipod
.diskname
;
136 m_device
= ipod
.targetname
;
137 m_mountpoint
= resolveMountPoint(ipod
.diskname
);
142 struct sansa_t sansa
;
143 n
= sansa_scan(&sansa
);
145 qDebug() << "Sansa found:" << sansa
.targetname
<< "at" << sansa
.diskname
;
146 m_device
= QString("sansa%1").arg(sansa
.targetname
);
147 m_mountpoint
= resolveMountPoint(sansa
.diskname
);
151 if(m_mountpoint
.isEmpty() && m_device
.isEmpty() && m_errdev
.isEmpty())
157 QStringList
Autodetection::getMountpoints()
159 #if defined(Q_OS_WIN32)
160 QStringList tempList
;
161 QFileInfoList list
= QDir::drives();
162 for(int i
=0; i
<list
.size();i
++)
164 tempList
<< list
.at(i
).absolutePath();
168 #elif defined(Q_OS_MACX)
169 QDir
dir("/Volumes");
170 return dir
.entryList();
171 #elif defined(Q_OS_LINUX)
172 QStringList tempList
;
174 FILE *mn
= setmntent("/etc/mtab", "r");
176 return QStringList("");
179 while((ent
= getmntent(mn
)))
180 tempList
<< QString(ent
->mnt_dir
);
185 #error Unknown Plattform
189 QString
Autodetection::resolveMountPoint(QString device
)
191 qDebug() << "Autodetection::resolveMountPoint(QString)" << device
;
193 #if defined(Q_OS_LINUX)
194 FILE *mn
= setmntent("/etc/mtab", "r");
199 while((ent
= getmntent(mn
))) {
200 if(QString(ent
->mnt_fsname
).startsWith(device
)
201 && QString(ent
->mnt_type
).contains("vfat", Qt::CaseInsensitive
)) {
203 return QString(ent
->mnt_dir
);
214 /** @brief detect devices based on usb pid / vid.
215 * @return true upon success, false otherwise.
217 bool Autodetection::detectUsb()
219 // autodetection uses the buildin device settings only
220 QSettings
dev(":/ini/rbutil.ini", QSettings::IniFormat
, this);
222 // get a list of ID -> target name
223 QStringList platforms
;
224 dev
.beginGroup("platforms");
225 platforms
= dev
.childKeys();
228 // usbids holds the mapping in the form
229 // ((VID<<16)|(PID)), targetname
230 // the ini file needs to hold the IDs as hex values.
231 QMap
<int, QString
> usbids
;
232 QMap
<int, QString
> usberror
;
234 for(int i
= 0; i
< platforms
.size(); i
++) {
235 dev
.beginGroup("platforms");
236 QString target
= dev
.value(platforms
.at(i
)).toString();
238 dev
.beginGroup(target
);
239 if(!dev
.value("usbid").toString().isEmpty())
240 usbids
.insert(dev
.value("usbid").toString().toInt(0, 16), target
);
241 if(!dev
.value("usberror").toString().isEmpty())
242 usberror
.insert(dev
.value("usberror").toString().toInt(0, 16), target
);
247 #if defined(Q_OS_LINUX) | defined(Q_OS_MACX)
252 b
= usb_get_busses();
255 qDebug() << "bus:" << b
->dirname
<< b
->devices
;
257 qDebug() << "devices present.";
258 struct usb_device
*u
;
262 id
= u
->descriptor
.idVendor
<< 16 | u
->descriptor
.idProduct
;
265 if(usbids
.contains(id
)) {
266 m_device
= usbids
.value(id
);
269 if(usberror
.contains(id
)) {
270 m_errdev
= usberror
.value(id
);
271 // we detected something, so return true
272 qDebug() << "detected device with problems via usb!";
282 #if defined(Q_OS_WIN32)
284 SP_DEVINFO_DATA infoData
;
287 // Iterate over all devices
288 // by doing it this way it's unneccessary to use GUIDs which might be not
289 // present in current MinGW. It also seemed to be more reliably than using
291 // See KB259695 for an example.
292 deviceInfo
= SetupDiGetClassDevs(NULL
, NULL
, NULL
, DIGCF_ALLCLASSES
| DIGCF_PRESENT
);
294 infoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
296 for(i
= 0; SetupDiEnumDeviceInfo(deviceInfo
, i
, &infoData
); i
++) {
298 LPTSTR buffer
= NULL
;
299 DWORD buffersize
= 0;
301 // get device desriptor first
302 // for some reason not doing so results in bad things (tm)
303 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
304 SPDRP_DEVICEDESC
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
305 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
306 if(buffer
) free(buffer
);
307 // double buffer size to avoid problems as per KB888609
308 buffer
= (LPTSTR
)malloc(buffersize
* 2);
315 // now get the hardware id, which contains PID and VID.
316 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
317 SPDRP_HARDWAREID
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
318 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
319 if(buffer
) free(buffer
);
320 // double buffer size to avoid problems as per KB888609
321 buffer
= (LPTSTR
)malloc(buffersize
* 2);
328 unsigned int vid
, pid
, rev
;
329 if(_stscanf(buffer
, _TEXT("USB\\Vid_%x&Pid_%x&Rev_%x"), &vid
, &pid
, &rev
) != 3) {
330 qDebug() << "Error getting USB ID -- possibly no USB device";
334 id
= vid
<< 16 | pid
;
335 qDebug("VID: %04x PID: %04x", vid
, pid
);
336 if(usbids
.contains(id
)) {
337 m_device
= usbids
.value(id
);
338 if(buffer
) free(buffer
);
339 SetupDiDestroyDeviceInfoList(deviceInfo
);
340 qDebug() << "detectUsb: Got" << m_device
;
343 if(usberror
.contains(id
)) {
344 m_errdev
= usberror
.value(id
);
345 // we detected something, so return true
346 if(buffer
) free(buffer
);
347 SetupDiDestroyDeviceInfoList(deviceInfo
);
348 qDebug() << "detectUsb: Got" << m_device
;
349 qDebug() << "detected device with problems via usb!";
353 if(buffer
) free(buffer
);
355 SetupDiDestroyDeviceInfoList(deviceInfo
);