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>
69 #include "rbsettings.h"
71 /** @brief detect permission of user (only Windows at moment).
72 * @return enum userlevel.
74 #if defined(Q_OS_WIN32)
75 enum System::userlevel
System::userPermissions(void)
78 NET_API_STATUS napistatus
;
79 wchar_t userbuf
[UNLEN
];
80 DWORD usersize
= UNLEN
;
82 enum userlevel result
;
84 status
= GetUserNameW(userbuf
, &usersize
);
88 napistatus
= NetUserGetInfo(NULL
, userbuf
, (DWORD
)1, (LPBYTE
*)&buf
);
90 switch(buf
->usri1_priv
) {
104 NetApiBufferFree(buf
);
109 /** @brief detects user permissions (only Windows at moment).
110 * @return a user readable string with the permission.
112 QString
System::userPermissionsString(void)
115 int perm
= userPermissions();
118 result
= QObject::tr("Guest");
121 result
= QObject::tr("Admin");
124 result
= QObject::tr("User");
127 result
= QObject::tr("Error");
135 /** @brief detects current Username.
136 * @return string with Username.
138 QString
System::userName(void)
140 #if defined(Q_OS_WIN32)
141 wchar_t userbuf
[UNLEN
];
142 DWORD usersize
= UNLEN
;
145 status
= GetUserNameW(userbuf
, &usersize
);
147 return QString::fromWCharArray(userbuf
);
149 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
151 user
= getpwuid(geteuid());
152 return QString(user
->pw_name
);
157 /** @brief detects the OS Version
158 * @return String with OS Version.
160 QString
System::osVersionString(void)
163 #if defined(Q_OS_WIN32)
165 ZeroMemory(&osvi
, sizeof(OSVERSIONINFO
));
166 osvi
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
169 result
= QString("Windows version %1.%2, ").arg(osvi
.dwMajorVersion
).arg(osvi
.dwMinorVersion
);
170 if(osvi
.szCSDVersion
)
171 result
+= QString("build %1 (%2)").arg(osvi
.dwBuildNumber
)
172 .arg(QString::fromWCharArray(osvi
.szCSDVersion
));
174 result
+= QString("build %1").arg(osvi
.dwBuildNumber
);
176 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
181 result
= QString("CPU: %1<br/>System: %2<br/>Release: %3<br/>Version: %4")
182 .arg(u
.machine
).arg(u
.sysname
).arg(u
.release
).arg(u
.version
);
184 result
+= QString("<br/>Qt version %1").arg(qVersion());
188 QList
<uint32_t> System::listUsbIds(void)
190 return listUsbDevices().keys();
193 /** @brief detect devices based on usb pid / vid.
194 * @return list with usb VID / PID values.
196 QMap
<uint32_t, QString
> System::listUsbDevices(void)
198 QMap
<uint32_t, QString
> usbids
;
200 qDebug() << "[System] Searching for USB devices";
201 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
203 libusb_device
**devs
;
206 res
= libusb_init(NULL
);
208 count
= libusb_get_device_list(NULL
, &devs
);
211 while((dev
= devs
[i
++]) != NULL
) {
213 unsigned char buf
[256];
215 struct libusb_device_descriptor descriptor
;
216 if(libusb_get_device_descriptor(dev
, &descriptor
) == 0) {
217 id
= descriptor
.idVendor
<< 16 | descriptor
.idProduct
;
219 libusb_device_handle
*dh
;
220 if(libusb_open(dev
, &dh
) == 0) {
221 libusb_get_string_descriptor_ascii(dh
, descriptor
.iManufacturer
, buf
, 256);
222 name
+= QString::fromAscii((char*)buf
) + " ";
223 libusb_get_string_descriptor_ascii(dh
, descriptor
.iProduct
, buf
, 256);
224 name
+= QString::fromAscii((char*)buf
);
228 name
= QObject::tr("(no description available)");
230 usbids
.insert(id
, name
);
231 qDebug("[System] USB: 0x%08x, %s", id
, name
.toLocal8Bit().data());
236 libusb_free_device_list(devs
, 1);
247 struct usb_device
*u
;
251 id
= u
->descriptor
.idVendor
<< 16 | u
->descriptor
.idProduct
;
252 // get identification strings
259 if(u
->descriptor
.iManufacturer
) {
260 res
= usb_get_string_simple(dev
, u
->descriptor
.iManufacturer
,
261 string
, sizeof(string
));
263 name
+= QString::fromAscii(string
) + " ";
265 if(u
->descriptor
.iProduct
) {
266 res
= usb_get_string_simple(dev
, u
->descriptor
.iProduct
,
267 string
, sizeof(string
));
269 name
+= QString::fromAscii(string
);
273 if(name
.isEmpty()) name
= QObject::tr("(no description available)");
276 usbids
.insert(id
, name
);
277 qDebug() << "[System] USB:" << QString("0x%1").arg(id
, 8, 16) << name
;
287 #if defined(Q_OS_WIN32)
289 SP_DEVINFO_DATA infoData
;
292 // Iterate over all devices
293 // by doing it this way it's unneccessary to use GUIDs which might be not
294 // present in current MinGW. It also seemed to be more reliably than using
296 // See KB259695 for an example.
297 deviceInfo
= SetupDiGetClassDevs(NULL
, NULL
, NULL
, DIGCF_ALLCLASSES
| DIGCF_PRESENT
);
299 infoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
301 for(i
= 0; SetupDiEnumDeviceInfo(deviceInfo
, i
, &infoData
); i
++) {
303 LPTSTR buffer
= NULL
;
304 DWORD buffersize
= 0;
307 // get device desriptor first
308 // for some reason not doing so results in bad things (tm)
309 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
310 SPDRP_DEVICEDESC
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
311 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
312 if(buffer
) free(buffer
);
313 // double buffer size to avoid problems as per KB888609
314 buffer
= (LPTSTR
)malloc(buffersize
* 2);
321 // now get the hardware id, which contains PID and VID.
322 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
323 SPDRP_LOCATION_INFORMATION
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
324 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
325 if(buffer
) free(buffer
);
326 // double buffer size to avoid problems as per KB888609
327 buffer
= (LPTSTR
)malloc(buffersize
* 2);
333 description
= QString::fromWCharArray(buffer
);
335 while(!SetupDiGetDeviceRegistryProperty(deviceInfo
, &infoData
,
336 SPDRP_HARDWAREID
,&data
, (PBYTE
)buffer
, buffersize
, &buffersize
)) {
337 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER
) {
338 if(buffer
) free(buffer
);
339 // double buffer size to avoid problems as per KB888609
340 buffer
= (LPTSTR
)malloc(buffersize
* 2);
347 unsigned int vid
, pid
;
348 if(_stscanf(buffer
, _TEXT("USB\\Vid_%x&Pid_%x"), &vid
, &pid
) == 2) {
350 id
= vid
<< 16 | pid
;
351 usbids
.insert(id
, description
);
352 qDebug("[System] USB VID: %04x, PID: %04x", vid
, pid
);
354 if(buffer
) free(buffer
);
356 SetupDiDestroyDeviceInfoList(deviceInfo
);
363 /** @brief detects current system proxy
364 * @return QUrl with proxy or empty
366 QUrl
System::systemProxy(void)
368 #if defined(Q_OS_LINUX)
369 return QUrl(getenv("http_proxy"));
370 #elif defined(Q_OS_WIN32)
372 wchar_t proxyval
[80];
376 DWORD enalen
= sizeof(DWORD
);
378 ret
= RegOpenKeyEx(HKEY_CURRENT_USER
,
379 _TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
380 0, KEY_QUERY_VALUE
, &hk
);
381 if(ret
!= ERROR_SUCCESS
) return QUrl("");
383 ret
= RegQueryValueEx(hk
, _TEXT("ProxyServer"), NULL
, NULL
, (LPBYTE
)proxyval
, &buflen
);
384 if(ret
!= ERROR_SUCCESS
) return QUrl("");
386 ret
= RegQueryValueEx(hk
, _TEXT("ProxyEnable"), NULL
, NULL
, (LPBYTE
)&enable
, &enalen
);
387 if(ret
!= ERROR_SUCCESS
) return QUrl("");
391 //qDebug() << QString::fromWCharArray(proxyval) << QString("%1").arg(enable);
393 return QUrl("http://" + QString::fromWCharArray(proxyval
));
396 #elif defined(Q_OS_MACX)
398 CFDictionaryRef dictref
;
399 CFStringRef stringref
;
400 CFNumberRef numberref
;
403 unsigned int bufsize
= 0;
407 dictref
= SCDynamicStoreCopyProxies(NULL
);
408 stringref
= (CFStringRef
)CFDictionaryGetValue(dictref
, kSCPropNetProxiesHTTPProxy
);
409 numberref
= (CFNumberRef
)CFDictionaryGetValue(dictref
, kSCPropNetProxiesHTTPEnable
);
410 CFNumberGetValue(numberref
, kCFNumberIntType
, &enable
);
412 // get number of characters. CFStringGetLength uses UTF-16 code pairs
413 bufsize
= CFStringGetLength(stringref
) * 2 + 1;
414 buf
= (char*)malloc(sizeof(char) * bufsize
);
416 qDebug() << "[System] can't allocate memory for proxy string!";
420 CFStringGetCString(stringref
, buf
, bufsize
, kCFStringEncodingUTF16
);
421 numberref
= (CFNumberRef
)CFDictionaryGetValue(dictref
, kSCPropNetProxiesHTTPPort
);
422 CFNumberGetValue(numberref
, kCFNumberIntType
, &port
);
423 proxy
.setScheme("http");
424 proxy
.setHost(QString::fromUtf16((unsigned short*)buf
));