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 <libusb-1.0/libusb.h>
48 #include <sys/utsname.h>
54 #if defined(Q_OS_LINUX)
59 #if defined(Q_OS_MACX)
60 #include <sys/param.h>
61 #include <sys/ucred.h>
62 #include <sys/mount.h>
64 #include <CoreFoundation/CoreFoundation.h>
65 #include <SystemConfiguration/SystemConfiguration.h>
66 #include <CoreServices/CoreServices.h>
70 #include "rbsettings.h"
72 /** @brief detect permission of user (only Windows at moment).
73 * @return enum userlevel.
75 #if defined(Q_OS_WIN32)
76 enum System::userlevel
System::userPermissions(void)
79 NET_API_STATUS napistatus
;
80 wchar_t userbuf
[UNLEN
];
81 DWORD usersize
= UNLEN
;
83 enum userlevel result
;
85 status
= GetUserNameW(userbuf
, &usersize
);
89 napistatus
= NetUserGetInfo(NULL
, userbuf
, (DWORD
)1, (LPBYTE
*)&buf
);
91 switch(buf
->usri1_priv
) {
105 NetApiBufferFree(buf
);
110 /** @brief detects user permissions (only Windows at moment).
111 * @return a user readable string with the permission.
113 QString
System::userPermissionsString(void)
116 int perm
= userPermissions();
119 result
= tr("Guest");
122 result
= tr("Admin");
128 result
= tr("Error");
136 /** @brief detects current Username.
137 * @return string with Username.
139 QString
System::userName(void)
141 #if defined(Q_OS_WIN32)
142 wchar_t userbuf
[UNLEN
];
143 DWORD usersize
= UNLEN
;
146 status
= GetUserNameW(userbuf
, &usersize
);
148 return QString::fromWCharArray(userbuf
);
150 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
152 user
= getpwuid(geteuid());
153 return QString(user
->pw_name
);
158 /** @brief detects the OS Version
159 * @return String with OS Version.
161 QString
System::osVersionString(void)
164 #if defined(Q_OS_WIN32)
166 ZeroMemory(&osvi
, sizeof(OSVERSIONINFO
));
167 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
170 result
= QString("Windows version %1.%2, ").arg(osvi
.dwMajorVersion
).arg(osvi
.dwMinorVersion
);
171 if(osvi
.szCSDVersion
)
172 result
+= QString("build %1 (%2)").arg(osvi
.dwBuildNumber
)
173 .arg(QString::fromWCharArray(osvi
.szCSDVersion
));
175 result
+= QString("build %1").arg(osvi
.dwBuildNumber
);
177 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
182 result
= QString("CPU: %1<br/>System: %2<br/>Release: %3<br/>Version: %4")
183 .arg(u
.machine
).arg(u
.sysname
).arg(u
.release
).arg(u
.version
);
184 #if defined(Q_OS_MACX)
189 error
= Gestalt(gestaltSystemVersionMajor
, &major
);
190 error
= Gestalt(gestaltSystemVersionMinor
, &minor
);
191 error
= Gestalt(gestaltSystemVersionBugFix
, &bugfix
);
193 result
+= QString("<br/>OS X %1.%2.%3 ").arg(major
).arg(minor
).arg(bugfix
);
194 // 1: 86k, 2: ppc, 10: i386
196 error
= Gestalt(gestaltSysArchitecture
, &arch
);
199 result
.append("(86k)");
202 result
.append("(ppc)");
205 result
.append("(x86)");
208 result
.append("(unknown)");
213 result
+= QString("<br/>Qt version %1").arg(qVersion());
217 QList
<uint32_t> System::listUsbIds(void)
219 return listUsbDevices().keys();
222 /** @brief detect devices based on usb pid / vid.
223 * @return list with usb VID / PID values.
225 QMap
<uint32_t, QString
> System::listUsbDevices(void)
227 QMap
<uint32_t, QString
> usbids
;
229 qDebug() << "[System] Searching for USB devices";
230 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
232 libusb_device
**devs
;
235 res
= libusb_init(NULL
);
237 count
= libusb_get_device_list(NULL
, &devs
);
240 while((dev
= devs
[i
++]) != NULL
) {
242 unsigned char buf
[256];
244 struct libusb_device_descriptor descriptor
;
245 if(libusb_get_device_descriptor(dev
, &descriptor
) == 0) {
246 id
= descriptor
.idVendor
<< 16 | descriptor
.idProduct
;
248 libusb_device_handle
*dh
;
249 if(libusb_open(dev
, &dh
) == 0) {
250 libusb_get_string_descriptor_ascii(dh
, descriptor
.iManufacturer
, buf
, 256);
251 name
+= QString::fromAscii((char*)buf
) + " ";
252 libusb_get_string_descriptor_ascii(dh
, descriptor
.iProduct
, buf
, 256);
253 name
+= QString::fromAscii((char*)buf
);
257 name
= tr("(no description available)");
259 usbids
.insert(id
, name
);
260 qDebug("[System] USB: 0x%08x, %s", id
, name
.toLocal8Bit().data());
265 libusb_free_device_list(devs
, 1);
276 struct usb_device
*u
;
280 id
= u
->descriptor
.idVendor
<< 16 | u
->descriptor
.idProduct
;
281 // get identification strings
288 if(u
->descriptor
.iManufacturer
) {
289 res
= usb_get_string_simple(dev
, u
->descriptor
.iManufacturer
,
290 string
, sizeof(string
));
292 name
+= QString::fromAscii(string
) + " ";
294 if(u
->descriptor
.iProduct
) {
295 res
= usb_get_string_simple(dev
, u
->descriptor
.iProduct
,
296 string
, sizeof(string
));
298 name
+= QString::fromAscii(string
);
302 if(name
.isEmpty()) name
= tr("(no description available)");
305 usbids
.insert(id
, name
);
306 qDebug() << "[System] USB:" << QString("0x%1").arg(id
, 8, 16) << name
;
316 #if defined(Q_OS_WIN32)
318 SP_DEVINFO_DATA infoData
;
321 // Iterate over all devices
322 // by doing it this way it's unneccessary to use GUIDs which might be not
323 // present in current MinGW. It also seemed to be more reliably than using
325 // See KB259695 for an example.
326 deviceInfo
= SetupDiGetClassDevs(NULL
, NULL
, NULL
, DIGCF_ALLCLASSES
| DIGCF_PRESENT
);
328 infoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
330 for(i
= 0; SetupDiEnumDeviceInfo(deviceInfo
, i
, &infoData
); i
++) {
332 LPTSTR buffer
= NULL
;
333 DWORD buffersize
= 0;
336 // get device desriptor first
337 // for some reason not doing so results in bad things (tm)
338 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
339 SPDRP_DEVICEDESC
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
340 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
341 if(buffer
) free(buffer
);
342 // double buffer size to avoid problems as per KB888609
343 buffer
= (LPTSTR
)malloc(buffersize
* 2);
350 // now get the hardware id, which contains PID and VID.
351 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
352 SPDRP_LOCATION_INFORMATION
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
353 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
354 if(buffer
) free(buffer
);
355 // double buffer size to avoid problems as per KB888609
356 buffer
= (LPTSTR
)malloc(buffersize
* 2);
362 description
= QString::fromWCharArray(buffer
);
364 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
365 SPDRP_HARDWAREID
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
366 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
367 if(buffer
) free(buffer
);
368 // double buffer size to avoid problems as per KB888609
369 buffer
= (LPTSTR
)malloc(buffersize
* 2);
376 unsigned int vid
, pid
;
377 if(_stscanf(buffer
, _TEXT("USB\\Vid_%x&Pid_%x"), &vid
, &pid
) == 2) {
379 id
= vid
<< 16 | pid
;
380 usbids
.insert(id
, description
);
381 qDebug("[System] USB VID: %04x, PID: %04x", vid
, pid
);
383 if(buffer
) free(buffer
);
385 SetupDiDestroyDeviceInfoList(deviceInfo
);
392 /** @brief detects current system proxy
393 * @return QUrl with proxy or empty
395 QUrl
System::systemProxy(void)
397 #if defined(Q_OS_LINUX)
398 return QUrl(getenv("http_proxy"));
399 #elif defined(Q_OS_WIN32)
401 wchar_t proxyval
[80];
405 DWORD enalen
= sizeof(DWORD
);
407 ret
= RegOpenKeyEx(HKEY_CURRENT_USER
,
408 _TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
409 0, KEY_QUERY_VALUE
, &hk
);
410 if(ret
!= ERROR_SUCCESS
) return QUrl("");
412 ret
= RegQueryValueEx(hk
, _TEXT("ProxyServer"), NULL
, NULL
, (LPBYTE
)proxyval
, &buflen
);
413 if(ret
!= ERROR_SUCCESS
) return QUrl("");
415 ret
= RegQueryValueEx(hk
, _TEXT("ProxyEnable"), NULL
, NULL
, (LPBYTE
)&enable
, &enalen
);
416 if(ret
!= ERROR_SUCCESS
) return QUrl("");
420 //qDebug() << QString::fromWCharArray(proxyval) << QString("%1").arg(enable);
422 return QUrl("http://" + QString::fromWCharArray(proxyval
));
425 #elif defined(Q_OS_MACX)
427 CFDictionaryRef dictref
;
428 CFStringRef stringref
;
429 CFNumberRef numberref
;
432 unsigned int bufsize
= 0;
436 dictref
= SCDynamicStoreCopyProxies(NULL
);
437 stringref
= (CFStringRef
)CFDictionaryGetValue(dictref
, kSCPropNetProxiesHTTPProxy
);
438 numberref
= (CFNumberRef
)CFDictionaryGetValue(dictref
, kSCPropNetProxiesHTTPEnable
);
439 CFNumberGetValue(numberref
, kCFNumberIntType
, &enable
);
441 // get number of characters. CFStringGetLength uses UTF-16 code pairs
442 bufsize
= CFStringGetLength(stringref
) * 2 + 1;
443 buf
= (char*)malloc(sizeof(char) * bufsize
);
445 qDebug() << "[System] can't allocate memory for proxy string!";
449 CFStringGetCString(stringref
, buf
, bufsize
, kCFStringEncodingUTF16
);
450 numberref
= (CFNumberRef
)CFDictionaryGetValue(dictref
, kSCPropNetProxiesHTTPPort
);
451 CFNumberGetValue(numberref
, kCFNumberIntType
, &port
);
452 proxy
.setScheme("http");
453 proxy
.setHost(QString::fromUtf16((unsigned short*)buf
));