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 ****************************************************************************/
30 #if defined(Q_OS_WIN32)
41 // Linux and Mac includes
42 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
44 #include <sys/utsname.h>
50 #if defined(Q_OS_LINUX)
55 #if defined(Q_OS_MACX)
56 #include <sys/param.h>
57 #include <sys/ucred.h>
58 #include <sys/mount.h>
62 #include "rbsettings.h"
64 /** @brief detect permission of user (only Windows at moment).
65 * @return enum userlevel.
67 #if defined(Q_OS_WIN32)
68 enum Detect::userlevel
Detect::userPermissions(void)
71 NET_API_STATUS napistatus
;
72 wchar_t userbuf
[UNLEN
];
73 DWORD usersize
= UNLEN
;
75 enum userlevel result
;
77 status
= GetUserNameW(userbuf
, &usersize
);
81 napistatus
= NetUserGetInfo(NULL
, userbuf
, (DWORD
)1, (LPBYTE
*)&buf
);
83 switch(buf
->usri1_priv
) {
97 NetApiBufferFree(buf
);
102 /** @brief detects user permissions (only Windows at moment).
103 * @return a user readable string with the permission.
105 QString
Detect::userPermissionsString(void)
108 int perm
= userPermissions();
111 result
= QObject::tr("Guest");
114 result
= QObject::tr("Admin");
117 result
= QObject::tr("User");
120 result
= QObject::tr("Error");
128 /** @brief detects current Username.
129 * @return string with Username.
131 QString
Detect::userName(void)
133 #if defined(Q_OS_WIN32)
134 wchar_t userbuf
[UNLEN
];
135 DWORD usersize
= UNLEN
;
138 status
= GetUserNameW(userbuf
, &usersize
);
140 return QString::fromWCharArray(userbuf
);
142 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
144 user
= getpwuid(geteuid());
145 return QString(user
->pw_name
);
150 /** @brief detects the OS Version
151 * @return String with OS Version.
153 QString
Detect::osVersionString(void)
156 #if defined(Q_OS_WIN32)
158 ZeroMemory(&osvi
, sizeof(OSVERSIONINFO
));
159 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
162 result
= QString("Windows version %1.%2, ").arg(osvi
.dwMajorVersion
).arg(osvi
.dwMinorVersion
);
163 if(osvi
.szCSDVersion
)
164 result
+= QString("build %1 (%2)").arg(osvi
.dwBuildNumber
)
165 .arg(QString::fromWCharArray(osvi
.szCSDVersion
));
167 result
+= QString("build %1").arg(osvi
.dwBuildNumber
);
169 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
174 result
= QString("CPU: %1<br/>System: %2<br/>Release: %3<br/>Version: %4")
175 .arg(u
.machine
).arg(u
.sysname
).arg(u
.release
).arg(u
.version
);
177 result
+= QString("<br/>Qt version %1").arg(qVersion());
181 QList
<uint32_t> Detect::listUsbIds(void)
183 return listUsbDevices().keys();
186 /** @brief detect devices based on usb pid / vid.
187 * @return list with usb VID / PID values.
189 QMap
<uint32_t, QString
> Detect::listUsbDevices(void)
191 QMap
<uint32_t, QString
> usbids
;
193 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
201 qDebug() << "bus:" << b
->dirname
<< b
->devices
;
203 qDebug() << "devices present.";
204 struct usb_device
*u
;
208 id
= u
->descriptor
.idVendor
<< 16 | u
->descriptor
.idProduct
;
209 // get identification strings
216 if(u
->descriptor
.iManufacturer
) {
217 res
= usb_get_string_simple(dev
, u
->descriptor
.iManufacturer
, string
, sizeof(string
));
219 name
+= QString::fromAscii(string
) + " ";
221 if(u
->descriptor
.iProduct
) {
222 res
= usb_get_string_simple(dev
, u
->descriptor
.iProduct
, string
, sizeof(string
));
224 name
+= QString::fromAscii(string
);
228 if(name
.isEmpty()) name
= QObject::tr("(no description available)");
230 if(id
) usbids
.insert(id
, name
);
238 #if defined(Q_OS_WIN32)
240 SP_DEVINFO_DATA infoData
;
243 // Iterate over all devices
244 // by doing it this way it's unneccessary to use GUIDs which might be not
245 // present in current MinGW. It also seemed to be more reliably than using
247 // See KB259695 for an example.
248 deviceInfo
= SetupDiGetClassDevs(NULL
, NULL
, NULL
, DIGCF_ALLCLASSES
| DIGCF_PRESENT
);
250 infoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
252 for(i
= 0; SetupDiEnumDeviceInfo(deviceInfo
, i
, &infoData
); i
++) {
254 LPTSTR buffer
= NULL
;
255 DWORD buffersize
= 0;
258 // get device desriptor first
259 // for some reason not doing so results in bad things (tm)
260 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
261 SPDRP_DEVICEDESC
,&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 // now get the hardware id, which contains PID and VID.
273 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
274 SPDRP_LOCATION_INFORMATION
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
275 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
276 if(buffer
) free(buffer
);
277 // double buffer size to avoid problems as per KB888609
278 buffer
= (LPTSTR
)malloc(buffersize
* 2);
284 description
= QString::fromWCharArray(buffer
);
286 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
287 SPDRP_HARDWAREID
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
288 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
289 if(buffer
) free(buffer
);
290 // double buffer size to avoid problems as per KB888609
291 buffer
= (LPTSTR
)malloc(buffersize
* 2);
298 unsigned int vid
, pid
, rev
;
299 if(_stscanf(buffer
, _TEXT("USB\\Vid_%x&Pid_%x&Rev_%x"), &vid
, &pid
, &rev
) == 3) {
301 id
= vid
<< 16 | pid
;
302 usbids
.insert(id
, description
);
303 qDebug("VID: %04x, PID: %04x", vid
, pid
);
305 if(buffer
) free(buffer
);
307 SetupDiDestroyDeviceInfoList(deviceInfo
);
314 /** @brief detects current system proxy
315 * @return QUrl with proxy or empty
317 QUrl
Detect::systemProxy(void)
319 #if defined(Q_OS_LINUX)
320 return QUrl(getenv("http_proxy"));
321 #elif defined(Q_OS_WIN32)
323 wchar_t proxyval
[80];
327 DWORD enalen
= sizeof(DWORD
);
329 ret
= RegOpenKeyEx(HKEY_CURRENT_USER
,
330 _TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
331 0, KEY_QUERY_VALUE
, &hk
);
332 if(ret
!= ERROR_SUCCESS
) return QUrl("");
334 ret
= RegQueryValueEx(hk
, _TEXT("ProxyServer"), NULL
, NULL
, (LPBYTE
)proxyval
, &buflen
);
335 if(ret
!= ERROR_SUCCESS
) return QUrl("");
337 ret
= RegQueryValueEx(hk
, _TEXT("ProxyEnable"), NULL
, NULL
, (LPBYTE
)&enable
, &enalen
);
338 if(ret
!= ERROR_SUCCESS
) return QUrl("");
342 //qDebug() << QString::fromWCharArray(proxyval) << QString("%1").arg(enable);
344 return QUrl("http://" + QString::fromWCharArray(proxyval
));
353 /** @brief detects the installed Rockbox version
354 * @return QString with version. Empty if not aviable
356 QString
Detect::installedVersion(QString mountpoint
)
358 RockboxInfo
info(mountpoint
);
364 return info
.version();
368 /** @brief detects installed rockbox target string
369 * @return target name (platform) of installed Rockbox, empty string on error.
371 QString
Detect::installedTarget(QString mountpoint
)
373 RockboxInfo
info(mountpoint
);
379 return info
.target();
383 /** @brief checks different Enviroment things. Ask if user wants to continue.
384 * @param settings A pointer to rbutils settings class
385 * @param permission if it should check for permission
386 * @param targetId the targetID to check for. if it is -1 no check is done.
387 * @return string with error messages if problems occurred, empty strings if none.
389 QString
Detect::check(bool permission
)
396 #if defined(Q_OS_WIN32)
397 if(Detect::userPermissions() != Detect::ADMIN
)
399 text
+= QObject::tr("<li>Permissions insufficient for bootloader "
400 "installation.\nAdministrator priviledges are necessary.</li>");
406 QString installed
= installedTarget(RbSettings::value(RbSettings::Mountpoint
).toString());
407 if(!installed
.isEmpty() && installed
!= RbSettings::value(RbSettings::CurConfigureModel
).toString())
409 text
+= QObject::tr("<li>Target mismatch detected.\n"
410 "Installed target: %1, selected target: %2.</li>")
411 .arg(installed
, RbSettings::value(RbSettings::CurPlatformName
).toString());
412 // FIXME: replace installed by human-friendly name
416 return QObject::tr("Problem detected:") + "<ul>" + text
+ "</ul>";