rockbox/rbutil/rbutilqt/base/system.cpp
Dominik Riebeling e2f5086916 Clean up and rename Detect class.
Move check() function out of the Detect class and place it into utils.cpp for now. Rename Detect class to System, as it now only retrieves data about the underlying system and doesn't detect anything anymore. Cleans up with the confusion between Detect and Autodetection.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22238 a1c6a512-1295-4272-9138-f99709370657
2009-08-10 19:46:51 +00:00

398 lines
11 KiB
C++

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2007 by Dominik Wenger
* $Id$
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "system.h"
#include <QtCore>
#include <QDebug>
#include <cstdlib>
#include <stdio.h>
// Windows Includes
#if defined(Q_OS_WIN32)
#if defined(UNICODE)
#define _UNICODE
#endif
#include <windows.h>
#include <tchar.h>
#include <lm.h>
#include <windows.h>
#include <setupapi.h>
#endif
// Linux and Mac includes
#if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
#if defined(LIBUSB1)
#include <libusb-1.0/libusb.h>
#else
#include <usb.h>
#endif
#include <sys/utsname.h>
#include <unistd.h>
#include <pwd.h>
#endif
// Linux includes
#if defined(Q_OS_LINUX)
#include <mntent.h>
#endif
// Mac includes
#if defined(Q_OS_MACX)
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/mount.h>
#endif
#include "utils.h"
#include "rbsettings.h"
/** @brief detect permission of user (only Windows at moment).
* @return enum userlevel.
*/
#if defined(Q_OS_WIN32)
enum System::userlevel System::userPermissions(void)
{
LPUSER_INFO_1 buf;
NET_API_STATUS napistatus;
wchar_t userbuf[UNLEN];
DWORD usersize = UNLEN;
BOOL status;
enum userlevel result;
status = GetUserNameW(userbuf, &usersize);
if(!status)
return ERR;
napistatus = NetUserGetInfo(NULL, userbuf, (DWORD)1, (LPBYTE*)&buf);
switch(buf->usri1_priv) {
case USER_PRIV_GUEST:
result = GUEST;
break;
case USER_PRIV_USER:
result = USER;
break;
case USER_PRIV_ADMIN:
result = ADMIN;
break;
default:
result = ERR;
break;
}
NetApiBufferFree(buf);
return result;
}
/** @brief detects user permissions (only Windows at moment).
* @return a user readable string with the permission.
*/
QString System::userPermissionsString(void)
{
QString result;
int perm = userPermissions();
switch(perm) {
case GUEST:
result = QObject::tr("Guest");
break;
case ADMIN:
result = QObject::tr("Admin");
break;
case USER:
result = QObject::tr("User");
break;
default:
result = QObject::tr("Error");
break;
}
return result;
}
#endif
/** @brief detects current Username.
* @return string with Username.
*/
QString System::userName(void)
{
#if defined(Q_OS_WIN32)
wchar_t userbuf[UNLEN];
DWORD usersize = UNLEN;
BOOL status;
status = GetUserNameW(userbuf, &usersize);
return QString::fromWCharArray(userbuf);
#endif
#if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
struct passwd *user;
user = getpwuid(geteuid());
return QString(user->pw_name);
#endif
}
/** @brief detects the OS Version
* @return String with OS Version.
*/
QString System::osVersionString(void)
{
QString result;
#if defined(Q_OS_WIN32)
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
result = QString("Windows version %1.%2, ").arg(osvi.dwMajorVersion).arg(osvi.dwMinorVersion);
if(osvi.szCSDVersion)
result += QString("build %1 (%2)").arg(osvi.dwBuildNumber)
.arg(QString::fromWCharArray(osvi.szCSDVersion));
else
result += QString("build %1").arg(osvi.dwBuildNumber);
#endif
#if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
struct utsname u;
int ret;
ret = uname(&u);
result = QString("CPU: %1<br/>System: %2<br/>Release: %3<br/>Version: %4")
.arg(u.machine).arg(u.sysname).arg(u.release).arg(u.version);
#endif
result += QString("<br/>Qt version %1").arg(qVersion());
return result;
}
QList<uint32_t> System::listUsbIds(void)
{
return listUsbDevices().keys();
}
/** @brief detect devices based on usb pid / vid.
* @return list with usb VID / PID values.
*/
QMap<uint32_t, QString> System::listUsbDevices(void)
{
QMap<uint32_t, QString> usbids;
// usb pid detection
qDebug() << "[System] Searching for USB devices";
#if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
#if defined(LIBUSB1)
libusb_device **devs;
int res;
ssize_t count;
res = libusb_init(NULL);
count = libusb_get_device_list(NULL, &devs);
libusb_device *dev;
int i = 0;
while((dev = devs[i++]) != NULL) {
QString name;
unsigned char buf[256];
uint32_t id;
struct libusb_device_descriptor descriptor;
if(libusb_get_device_descriptor(dev, &descriptor) == 0) {
id = descriptor.idVendor << 16 | descriptor.idProduct;
libusb_device_handle *dh;
if(libusb_open(dev, &dh) == 0) {
libusb_get_string_descriptor_ascii(dh, descriptor.iManufacturer, buf, 256);
name += QString::fromAscii((char*)buf) + " ";
libusb_get_string_descriptor_ascii(dh, descriptor.iProduct, buf, 256);
name += QString::fromAscii((char*)buf);
libusb_close(dh);
}
if(name.isEmpty())
name = QObject::tr("(no description available)");
if(id) {
usbids.insert(id, name);
qDebug("[System] USB: 0x%08x, %s", id, name.toLocal8Bit().data());
}
}
}
libusb_free_device_list(devs, 1);
libusb_exit(NULL);
#else
usb_init();
usb_find_busses();
usb_find_devices();
struct usb_bus *b;
b = usb_busses;
while(b) {
if(b->devices) {
struct usb_device *u;
u = b->devices;
while(u) {
uint32_t id;
id = u->descriptor.idVendor << 16 | u->descriptor.idProduct;
// get identification strings
usb_dev_handle *dev;
QString name;
char string[256];
int res;
dev = usb_open(u);
if(dev) {
if(u->descriptor.iManufacturer) {
res = usb_get_string_simple(dev, u->descriptor.iManufacturer,
string, sizeof(string));
if(res > 0)
name += QString::fromAscii(string) + " ";
}
if(u->descriptor.iProduct) {
res = usb_get_string_simple(dev, u->descriptor.iProduct,
string, sizeof(string));
if(res > 0)
name += QString::fromAscii(string);
}
}
usb_close(dev);
if(name.isEmpty()) name = QObject::tr("(no description available)");
if(id) {
usbids.insert(id, name);
qDebug() << "[System] USB:" << QString("0x%1").arg(id, 8, 16) << name;
}
u = u->next;
}
}
b = b->next;
}
#endif
#endif
#if defined(Q_OS_WIN32)
HDEVINFO deviceInfo;
SP_DEVINFO_DATA infoData;
DWORD i;
// Iterate over all devices
// by doing it this way it's unneccessary to use GUIDs which might be not
// present in current MinGW. It also seemed to be more reliably than using
// a GUID.
// See KB259695 for an example.
deviceInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
infoData.cbSize = sizeof(SP_DEVINFO_DATA);
for(i = 0; SetupDiEnumDeviceInfo(deviceInfo, i, &infoData); i++) {
DWORD data;
LPTSTR buffer = NULL;
DWORD buffersize = 0;
QString description;
// get device desriptor first
// for some reason not doing so results in bad things (tm)
while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData,
SPDRP_DEVICEDESC,&data, (PBYTE)buffer, buffersize, &buffersize)) {
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
if(buffer) free(buffer);
// double buffer size to avoid problems as per KB888609
buffer = (LPTSTR)malloc(buffersize * 2);
}
else {
break;
}
}
// now get the hardware id, which contains PID and VID.
while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData,
SPDRP_LOCATION_INFORMATION,&data, (PBYTE)buffer, buffersize, &buffersize)) {
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
if(buffer) free(buffer);
// double buffer size to avoid problems as per KB888609
buffer = (LPTSTR)malloc(buffersize * 2);
}
else {
break;
}
}
description = QString::fromWCharArray(buffer);
while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData,
SPDRP_HARDWAREID,&data, (PBYTE)buffer, buffersize, &buffersize)) {
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
if(buffer) free(buffer);
// double buffer size to avoid problems as per KB888609
buffer = (LPTSTR)malloc(buffersize * 2);
}
else {
break;
}
}
unsigned int vid, pid, rev;
if(_stscanf(buffer, _TEXT("USB\\Vid_%x&Pid_%x&Rev_%x"), &vid, &pid, &rev) == 3) {
uint32_t id;
id = vid << 16 | pid;
usbids.insert(id, description);
qDebug("[System] USB VID: %04x, PID: %04x", vid, pid);
}
if(buffer) free(buffer);
}
SetupDiDestroyDeviceInfoList(deviceInfo);
#endif
return usbids;
}
/** @brief detects current system proxy
* @return QUrl with proxy or empty
*/
QUrl System::systemProxy(void)
{
#if defined(Q_OS_LINUX)
return QUrl(getenv("http_proxy"));
#elif defined(Q_OS_WIN32)
HKEY hk;
wchar_t proxyval[80];
DWORD buflen = 80;
long ret;
DWORD enable;
DWORD enalen = sizeof(DWORD);
ret = RegOpenKeyEx(HKEY_CURRENT_USER,
_TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
0, KEY_QUERY_VALUE, &hk);
if(ret != ERROR_SUCCESS) return QUrl("");
ret = RegQueryValueEx(hk, _TEXT("ProxyServer"), NULL, NULL, (LPBYTE)proxyval, &buflen);
if(ret != ERROR_SUCCESS) return QUrl("");
ret = RegQueryValueEx(hk, _TEXT("ProxyEnable"), NULL, NULL, (LPBYTE)&enable, &enalen);
if(ret != ERROR_SUCCESS) return QUrl("");
RegCloseKey(hk);
//qDebug() << QString::fromWCharArray(proxyval) << QString("%1").arg(enable);
if(enable != 0)
return QUrl("http://" + QString::fromWCharArray(proxyval));
else
return QUrl("");
#else
return QUrl("");
#endif
}