1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id: detect.cpp 17769 2008-06-23 20:31:44Z Domonoky $
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 ****************************************************************************/
27 #include <QMessageBox>
31 #if defined(Q_OS_WIN32)
42 // Linux and Mac includes
43 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
45 #include <sys/utsname.h>
51 #if defined(Q_OS_LINUX)
56 #if defined(Q_OS_MACX)
57 #include <sys/param.h>
58 #include <sys/ucred.h>
59 #include <sys/mount.h>
63 /** @brief detect permission of user (only Windows at moment).
64 * @return enum userlevel.
66 #if defined(Q_OS_WIN32)
67 enum Detect::userlevel
Detect::userPermissions(void)
70 NET_API_STATUS napistatus
;
71 wchar_t userbuf
[UNLEN
];
72 DWORD usersize
= UNLEN
;
74 enum userlevel result
;
76 status
= GetUserNameW(userbuf
, &usersize
);
80 napistatus
= NetUserGetInfo(NULL
, userbuf
, (DWORD
)1, (LPBYTE
*)&buf
);
82 switch(buf
->usri1_priv
) {
96 NetApiBufferFree(buf
);
101 /** @brief detects user permissions (only Windows at moment).
102 * @return a user readable string with the permission.
104 QString
Detect::userPermissionsString(void)
107 int perm
= userPermissions();
110 result
= QObject::tr("Guest");
113 result
= QObject::tr("Admin");
116 result
= QObject::tr("User");
119 result
= QObject::tr("Error");
127 /** @brief detects current Username.
128 * @return string with Username.
130 QString
Detect::userName(void)
132 #if defined(Q_OS_WIN32)
133 wchar_t userbuf
[UNLEN
];
134 DWORD usersize
= UNLEN
;
137 status
= GetUserNameW(userbuf
, &usersize
);
139 return QString::fromWCharArray(userbuf
);
141 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
143 user
= getpwuid(geteuid());
144 return QString(user
->pw_name
);
149 /** @brief detects the OS Version
150 * @return String with OS Version.
152 QString
Detect::osVersionString(void)
155 #if defined(Q_OS_WIN32)
157 ZeroMemory(&osvi
, sizeof(OSVERSIONINFO
));
158 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
161 result
= QString("Windows version %1.%2, ").arg(osvi
.dwMajorVersion
).arg(osvi
.dwMinorVersion
);
162 result
+= QString("build %1 (%2)").arg(osvi
.dwBuildNumber
).arg(QString::fromWCharArray(osvi
.szCSDVersion
));
164 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
169 result
= QString("CPU: %1<br/>System: %2<br/>Release: %3<br/>Version: %4")
170 .arg(u
.machine
).arg(u
.sysname
).arg(u
.release
).arg(u
.version
);
175 QList
<uint32_t> Detect::listUsbIds(void)
177 return listUsbDevices().keys();
180 /** @brief detect devices based on usb pid / vid.
181 * @return list with usb VID / PID values.
183 QMap
<uint32_t, QString
> Detect::listUsbDevices(void)
185 QMap
<uint32_t, QString
> usbids
;
187 #if defined(Q_OS_LINUX) | defined(Q_OS_MACX)
195 qDebug() << "bus:" << b
->dirname
<< b
->devices
;
197 qDebug() << "devices present.";
198 struct usb_device
*u
;
202 id
= u
->descriptor
.idVendor
<< 16 | u
->descriptor
.idProduct
;
203 // FIXME: until description is empty for now.
204 if(id
) usbids
.insert(id
, QString(""));
212 #if defined(Q_OS_WIN32)
214 SP_DEVINFO_DATA infoData
;
217 // Iterate over all devices
218 // by doing it this way it's unneccessary to use GUIDs which might be not
219 // present in current MinGW. It also seemed to be more reliably than using
221 // See KB259695 for an example.
222 deviceInfo
= SetupDiGetClassDevs(NULL
, NULL
, NULL
, DIGCF_ALLCLASSES
| DIGCF_PRESENT
);
224 infoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
226 for(i
= 0; SetupDiEnumDeviceInfo(deviceInfo
, i
, &infoData
); i
++) {
228 LPTSTR buffer
= NULL
;
229 DWORD buffersize
= 0;
232 // get device desriptor first
233 // for some reason not doing so results in bad things (tm)
234 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
235 SPDRP_DEVICEDESC
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
236 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
237 if(buffer
) free(buffer
);
238 // double buffer size to avoid problems as per KB888609
239 buffer
= (LPTSTR
)malloc(buffersize
* 2);
246 // now get the hardware id, which contains PID and VID.
247 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
248 SPDRP_LOCATION_INFORMATION
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
249 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
250 if(buffer
) free(buffer
);
251 // double buffer size to avoid problems as per KB888609
252 buffer
= (LPTSTR
)malloc(buffersize
* 2);
258 description
= QString::fromWCharArray(buffer
);
260 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
261 SPDRP_HARDWAREID
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
262 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
263 if(buffer
) free(buffer
);
264 // double buffer size to avoid problems as per KB888609
265 buffer
= (LPTSTR
)malloc(buffersize
* 2);
272 unsigned int vid
, pid
, rev
;
273 if(_stscanf(buffer
, _TEXT("USB\\Vid_%x&Pid_%x&Rev_%x"), &vid
, &pid
, &rev
) == 3) {
275 id
= vid
<< 16 | pid
;
276 usbids
.insert(id
, description
);
277 qDebug("VID: %04x, PID: %04x", vid
, pid
);
279 if(buffer
) free(buffer
);
281 SetupDiDestroyDeviceInfoList(deviceInfo
);
288 /** @brief detects current system proxy
289 * @return QUrl with proxy or empty
291 QUrl
Detect::systemProxy(void)
293 #if defined(Q_OS_LINUX)
294 return QUrl(getenv("http_proxy"));
295 #elif defined(Q_OS_WIN32)
297 wchar_t proxyval
[80];
301 DWORD enalen
= sizeof(DWORD
);
303 ret
= RegOpenKeyEx(HKEY_CURRENT_USER
,
304 _TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
305 0, KEY_QUERY_VALUE
, &hk
);
306 if(ret
!= ERROR_SUCCESS
) return QUrl("");
308 ret
= RegQueryValueEx(hk
, _TEXT("ProxyServer"), NULL
, NULL
, (LPBYTE
)proxyval
, &buflen
);
309 if(ret
!= ERROR_SUCCESS
) return QUrl("");
311 ret
= RegQueryValueEx(hk
, _TEXT("ProxyEnable"), NULL
, NULL
, (LPBYTE
)&enable
, &enalen
);
312 if(ret
!= ERROR_SUCCESS
) return QUrl("");
316 //qDebug() << QString::fromWCharArray(proxyval) << QString("%1").arg(enable);
318 return QUrl("http://" + QString::fromWCharArray(proxyval
));
327 /** @brief detects the installed Rockbox version
328 * @return QString with version. Empty if not aviable
330 QString
Detect::installedVersion(QString mountpoint
)
332 // read rockbox-info.txt
333 QFile
info(mountpoint
+"/.rockbox/rockbox-info.txt");
334 if(!info
.open(QIODevice::ReadOnly
))
339 while (!info
.atEnd()) {
340 QString line
= info
.readLine();
342 if(line
.contains("Version:"))
344 return line
.remove("Version:").trimmed();
352 /** @brief detects installed rockbox target id
353 * @return TargetId of installed rockbox, or -1 if not available
355 int Detect::installedTargetId(QString mountpoint
)
357 // read rockbox-info.txt
358 QFile
info(mountpoint
+"/.rockbox/rockbox-info.txt");
359 if(!info
.open(QIODevice::ReadOnly
))
364 while (!info
.atEnd())
366 QString line
= info
.readLine();
367 if(line
.contains("Target id:"))
370 return line
.remove("Target id:").trimmed().toInt();
378 /** @brief checks different Enviroment things. Ask if user wants to continue.
379 * @param settings A pointer to rbutils settings class
380 * @param permission if it should check for permission
381 * @param targetId the targetID to check for. if it is -1 no check is done.
382 * @return true if everything is ok, or user wants to continue
384 bool Detect::check(RbSettings
* settings
,bool permission
,int targetId
)
391 #if defined(Q_OS_WIN32)
392 if(Detect::userPermissions() != Detect::ADMIN
)
394 text
+= QObject::tr("Permissions are not sufficient! \n Run with admin rights. \n\n");
402 int installedID
= Detect::installedTargetId(settings
->mountpoint());
403 if( installedID
!= -1 && installedID
!= targetId
)
405 text
+= QObject::tr("Target mismatch detected. \n\n"
406 "Installed target: %1.\n"
407 "New Target: %2.\n\n").arg(settings
->nameOfTargetId(installedID
),settings
->curName());
415 text
+= QObject::tr("\n Do you want to continue ?");
416 if(QMessageBox::warning(NULL
, QObject::tr("Problems detected"),text
,
417 QMessageBox::Yes
| QMessageBox::No
) == QMessageBox::No
)