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 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
= getUserPermissions();
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 /** @brief detect devices based on usb pid / vid.
176 * @return list with usb VID / PID values.
178 QList
<uint32_t> Detect::listUsbIds(void)
180 QList
<uint32_t> usbids
;
182 #if defined(Q_OS_LINUX) | defined(Q_OS_MACX)
190 qDebug() << "bus:" << b
->dirname
<< b
->devices
;
192 qDebug() << "devices present.";
193 struct usb_device
*u
;
197 id
= u
->descriptor
.idVendor
<< 16 | u
->descriptor
.idProduct
;
198 if(id
) usbids
.append(id
);
206 #if defined(Q_OS_WIN32)
208 SP_DEVINFO_DATA infoData
;
211 // Iterate over all devices
212 // by doing it this way it's unneccessary to use GUIDs which might be not
213 // present in current MinGW. It also seemed to be more reliably than using
215 // See KB259695 for an example.
216 deviceInfo
= SetupDiGetClassDevs(NULL
, NULL
, NULL
, DIGCF_ALLCLASSES
| DIGCF_PRESENT
);
218 infoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
220 for(i
= 0; SetupDiEnumDeviceInfo(deviceInfo
, i
, &infoData
); i
++) {
222 LPTSTR buffer
= NULL
;
223 DWORD buffersize
= 0;
225 // get device desriptor first
226 // for some reason not doing so results in bad things (tm)
227 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
228 SPDRP_DEVICEDESC
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
229 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
230 if(buffer
) free(buffer
);
231 // double buffer size to avoid problems as per KB888609
232 buffer
= (LPTSTR
)malloc(buffersize
* 2);
239 // now get the hardware id, which contains PID and VID.
240 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
241 SPDRP_HARDWAREID
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
242 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
243 if(buffer
) free(buffer
);
244 // double buffer size to avoid problems as per KB888609
245 buffer
= (LPTSTR
)malloc(buffersize
* 2);
252 unsigned int vid
, pid
, rev
;
253 if(_stscanf(buffer
, _TEXT("USB\\Vid_%x&Pid_%x&Rev_%x"), &vid
, &pid
, &rev
) != 3) {
254 qDebug() << "Error getting USB ID -- possibly no USB device";
258 id
= vid
<< 16 | pid
;
260 qDebug("VID: %04x PID: %04x", vid
, pid
);
262 if(buffer
) free(buffer
);
264 SetupDiDestroyDeviceInfoList(deviceInfo
);
271 /** @brief detects current system proxy
272 * @return QUrl with proxy or empty
274 QUrl
Detect::systemProxy(void)
276 #if defined(Q_OS_LINUX)
277 return QUrl(getenv("http_proxy"));
278 #elif defined(Q_OS_WIN32)
280 wchar_t proxyval
[80];
284 DWORD enalen
= sizeof(DWORD
);
286 ret
= RegOpenKeyEx(HKEY_CURRENT_USER
,
287 _TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
288 0, KEY_QUERY_VALUE
, &hk
);
289 if(ret
!= ERROR_SUCCESS
) return QUrl("");
291 ret
= RegQueryValueEx(hk
, _TEXT("ProxyServer"), NULL
, NULL
, (LPBYTE
)proxyval
, &buflen
);
292 if(ret
!= ERROR_SUCCESS
) return QUrl("");
294 ret
= RegQueryValueEx(hk
, _TEXT("ProxyEnable"), NULL
, NULL
, (LPBYTE
)&enable
, &enalen
);
295 if(ret
!= ERROR_SUCCESS
) return QUrl("");
299 //qDebug() << QString::fromWCharArray(proxyval) << QString("%1").arg(enable);
301 return QUrl("http://" + QString::fromWCharArray(proxyval
));
310 /** @brief detects the installed Rockbox version
311 * @return QString with version. Empty if not aviable
313 QString
Detect::installedVersion(QString mountpoint
)
315 // read rockbox-info.txt
316 QFile
info(mountpoint
+"/.rockbox/rockbox-info.txt");
317 if(!info
.open(QIODevice::ReadOnly
))
322 while (!info
.atEnd()) {
323 QString line
= info
.readLine();
325 if(line
.contains("Version:"))
327 return line
.remove("Version:").trimmed();
335 /** @brief detects installed rockbox target id
336 * @return TargetId of installed rockbox, or -1 if not available
338 int Detect::installedTargetId(QString mountpoint
)
340 // read rockbox-info.txt
341 QFile
info(mountpoint
+"/.rockbox/rockbox-info.txt");
342 if(!info
.open(QIODevice::ReadOnly
))
347 while (!info
.atEnd())
349 QString line
= info
.readLine();
350 if(line
.contains("Target id:"))
353 return line
.remove("Target id:").trimmed().toInt();
361 /** @brief checks different Enviroment things. Ask if user wants to continue.
362 * @param settings A pointer to rbutils settings class
363 * @param permission if it should check for permission
364 * @param targetId the targetID to check for. if it is -1 no check is done.
365 * @return true if everything is ok, or user wants to continue
367 bool Detect::check(RbSettings
* settings
,bool permission
,int targetId
)
374 #if defined(Q_OS_WIN32)
375 if(Detect::userPermissions() != Detect::ADMIN
)
377 text
+= QObject::tr("Permissions are not sufficient! \n Run with admin rights. \n\n");
385 int installedID
= Detect::installedTargetId(settings
->mountpoint());
386 if( installedID
!= -1 && installedID
!= targetId
)
388 text
+= QObject::tr("Target mismatch detected. \n\n"
389 "Installed target: %1.\n"
390 "New Target: %2.\n\n").arg(settings
->nameOfTargetId(installedID
),settings
->curName());
398 text
+= QObject::tr("\n Do you want to continue ?");
399 if(QMessageBox::warning(NULL
, QObject::tr("Problems detected"),text
,
400 QMessageBox::Yes
| QMessageBox::No
) == QMessageBox::No
)