Add a useful note regarding USB connection to the iAudio X5 installation chapter.
[Rockbox.git] / rbutil / rbutilqt / utils.cpp
blob9359522f04b58c3cfd947b2c6d62c49d27be47cd
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id$
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 ****************************************************************************/
20 #include "utils.h"
22 #include <QtCore>
23 #include <QDebug>
24 #include <cstdlib>
25 #include <stdio.h>
27 #if defined(Q_OS_WIN32)
28 #if defined(UNICODE)
29 #define _UNICODE
30 #endif
31 #include <windows.h>
32 #include <tchar.h>
33 #include <lm.h>
34 #endif
35 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
36 #include <usb.h>
37 #include <sys/utsname.h>
38 #include <unistd.h>
39 #include <pwd.h>
40 #endif
41 #if defined(Q_OS_LINUX)
42 #include <mntent.h>
43 #endif
44 #if defined(Q_OS_MACX)
45 #include <sys/param.h>
46 #include <sys/ucred.h>
47 #include <sys/mount.h>
48 #endif
49 #if defined(Q_OS_WIN32)
50 #if defined(UNICODE)
51 #define _UNICODE
52 #endif
53 #include <tchar.h>
54 #include <windows.h>
55 #include <setupapi.h>
56 #endif
58 // recursive function to delete a dir with files
59 bool recRmdir( const QString &dirName )
61 QString dirN = dirName;
62 QDir dir(dirN);
63 // make list of entries in directory
64 QStringList list = dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot);
65 QFileInfo fileInfo;
66 QString curItem, lstAt;
67 for(int i = 0; i < list.size(); i++){ // loop through all items of list
68 QString name = list.at(i);
69 curItem = dirN + "/" + name;
70 fileInfo.setFile(curItem);
71 if(fileInfo.isDir()) // is directory
72 recRmdir(curItem); // call recRmdir() recursively for deleting subdirectory
73 else // is file
74 QFile::remove(curItem); // ok, delete file
76 dir.cdUp();
77 return dir.rmdir(dirN); // delete empty dir and return if (now empty) dir-removing was successfull
81 //! @brief resolves the given path, ignoring case.
82 //! @param path absolute path to resolve.
83 //! @return returns exact casing of path, empty string if path not found.
84 QString resolvePathCase(QString path)
86 QStringList elems;
87 QString realpath;
89 elems = path.split("/", QString::SkipEmptyParts);
90 int start;
91 #if defined(Q_OS_WIN32)
92 // on windows we must make sure to start with the first entry (i.e. the
93 // drive letter) instead of a single / to make resolving work.
94 start = 1;
95 realpath = elems.at(0) + "/";
96 #else
97 start = 0;
98 realpath = "/";
99 #endif
101 for(int i = start; i < elems.size(); i++) {
102 QStringList direlems
103 = QDir(realpath).entryList(QDir::AllEntries|QDir::Hidden|QDir::System);
104 if(direlems.contains(elems.at(i), Qt::CaseInsensitive)) {
105 // need to filter using QRegExp as QStringList::filter(QString)
106 // matches any substring
107 QString expr = QString("^" + elems.at(i) + "$");
108 QRegExp rx = QRegExp(expr, Qt::CaseInsensitive);
109 QStringList a = direlems.filter(rx);
111 if(a.size() != 1)
112 return QString("");
113 if(!realpath.endsWith("/"))
114 realpath += "/";
115 realpath += a.at(0);
117 else
118 return QString("");
120 qDebug() << __func__ << path << "->" << realpath;
121 return realpath;
125 //! @brief get system proxy value.
126 QUrl systemProxy(void)
128 #if defined(Q_OS_LINUX)
129 return QUrl(getenv("http_proxy"));
130 #elif defined(Q_OS_WIN32)
131 HKEY hk;
132 wchar_t proxyval[80];
133 DWORD buflen = 80;
134 long ret;
135 DWORD enable;
136 DWORD enalen = sizeof(DWORD);
138 ret = RegOpenKeyEx(HKEY_CURRENT_USER,
139 _TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
140 0, KEY_QUERY_VALUE, &hk);
141 if(ret != ERROR_SUCCESS) return QUrl("");
143 ret = RegQueryValueEx(hk, _TEXT("ProxyServer"), NULL, NULL, (LPBYTE)proxyval, &buflen);
144 if(ret != ERROR_SUCCESS) return QUrl("");
146 ret = RegQueryValueEx(hk, _TEXT("ProxyEnable"), NULL, NULL, (LPBYTE)&enable, &enalen);
147 if(ret != ERROR_SUCCESS) return QUrl("");
149 RegCloseKey(hk);
151 //qDebug() << QString::fromWCharArray(proxyval) << QString("%1").arg(enable);
152 if(enable != 0)
153 return QUrl("http://" + QString::fromWCharArray(proxyval));
154 else
155 return QUrl("");
156 #else
157 return QUrl("");
158 #endif
161 QString installedVersion(QString mountpoint)
163 // read rockbox-info.txt
164 QFile info(mountpoint +"/.rockbox/rockbox-info.txt");
165 if(!info.open(QIODevice::ReadOnly))
167 return "";
170 QString target, features,version;
171 while (!info.atEnd()) {
172 QString line = info.readLine();
174 if(line.contains("Version:"))
176 return line.remove("Version:").trimmed();
179 info.close();
180 return "";
183 int installedTargetId(QString mountpoint)
185 // read rockbox-info.txt
186 QFile info(mountpoint +"/.rockbox/rockbox-info.txt");
187 if(!info.open(QIODevice::ReadOnly))
189 return -1;
192 QString target, features,version;
193 while (!info.atEnd()) {
194 QString line = info.readLine();
196 if(line.contains("Target id:"))
198 return line.remove("Target id:").trimmed().toInt();
201 info.close();
202 return -1;
206 QString getUserName(void)
208 #if defined(Q_OS_WIN32)
209 wchar_t userbuf[UNLEN];
210 DWORD usersize = UNLEN;
211 BOOL status;
213 status = GetUserNameW(userbuf, &usersize);
215 return QString::fromWCharArray(userbuf);
216 #endif
217 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
218 struct passwd *user;
219 user = getpwuid(geteuid());
220 return QString(user->pw_name);
221 #endif
225 #if defined(Q_OS_WIN32)
226 enum userlevel getUserPermissions(void)
228 LPUSER_INFO_1 buf;
229 NET_API_STATUS napistatus;
230 wchar_t userbuf[UNLEN];
231 DWORD usersize = UNLEN;
232 BOOL status;
233 enum userlevel result;
235 status = GetUserNameW(userbuf, &usersize);
236 if(!status)
237 return ERR;
239 napistatus = NetUserGetInfo(NULL, userbuf, (DWORD)1, (LPBYTE*)&buf);
241 switch(buf->usri1_priv) {
242 case USER_PRIV_GUEST:
243 result = GUEST;
244 break;
245 case USER_PRIV_USER:
246 result = USER;
247 break;
248 case USER_PRIV_ADMIN:
249 result = ADMIN;
250 break;
251 default:
252 result = ERR;
253 break;
255 NetApiBufferFree(buf);
257 return result;
260 QString getUserPermissionsString(void)
262 QString result;
263 int perm = getUserPermissions();
264 switch(perm) {
265 case GUEST:
266 result = QObject::tr("Guest");
267 break;
268 case ADMIN:
269 result = QObject::tr("Admin");
270 break;
271 case USER:
272 result = QObject::tr("User");
273 break;
274 default:
275 result = QObject::tr("Error");
276 break;
278 return result;
280 #endif
282 QString getOsVersionString(void)
284 QString result;
285 #if defined(Q_OS_WIN32)
286 OSVERSIONINFO osvi;
287 ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
288 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
289 GetVersionEx(&osvi);
291 result = QString("Windows version %1.%2, ").arg(osvi.dwMajorVersion).arg(osvi.dwMinorVersion);
292 result += QString("build %1 (%2)").arg(osvi.dwBuildNumber).arg(QString::fromWCharArray(osvi.szCSDVersion));
293 #endif
294 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
295 struct utsname u;
296 int ret;
297 ret = uname(&u);
299 result = QString("CPU: %1<br/>System: %2<br/>Release: %3<br/>Version: %4")
300 .arg(u.machine).arg(u.sysname).arg(u.release).arg(u.version);
301 #endif
302 return result;
306 /** @brief detect devices based on usb pid / vid.
307 * @return list with usb VID / PID values.
309 QList<uint32_t> listUsbIds(void)
311 QList<uint32_t> usbids;
312 // usb pid detection
313 #if defined(Q_OS_LINUX) | defined(Q_OS_MACX)
314 usb_init();
315 usb_find_busses();
316 usb_find_devices();
317 struct usb_bus *b;
318 b = usb_busses;
320 while(b) {
321 qDebug() << "bus:" << b->dirname << b->devices;
322 if(b->devices) {
323 qDebug() << "devices present.";
324 struct usb_device *u;
325 u = b->devices;
326 while(u) {
327 uint32_t id;
328 id = u->descriptor.idVendor << 16 | u->descriptor.idProduct;
329 if(id) usbids.append(id);
330 u = u->next;
333 b = b->next;
335 #endif
337 #if defined(Q_OS_WIN32)
338 HDEVINFO deviceInfo;
339 SP_DEVINFO_DATA infoData;
340 DWORD i;
342 // Iterate over all devices
343 // by doing it this way it's unneccessary to use GUIDs which might be not
344 // present in current MinGW. It also seemed to be more reliably than using
345 // a GUID.
346 // See KB259695 for an example.
347 deviceInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
349 infoData.cbSize = sizeof(SP_DEVINFO_DATA);
351 for(i = 0; SetupDiEnumDeviceInfo(deviceInfo, i, &infoData); i++) {
352 DWORD data;
353 LPTSTR buffer = NULL;
354 DWORD buffersize = 0;
356 // get device desriptor first
357 // for some reason not doing so results in bad things (tm)
358 while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData,
359 SPDRP_DEVICEDESC,&data, (PBYTE)buffer, buffersize, &buffersize)) {
360 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
361 if(buffer) free(buffer);
362 // double buffer size to avoid problems as per KB888609
363 buffer = (LPTSTR)malloc(buffersize * 2);
365 else {
366 break;
370 // now get the hardware id, which contains PID and VID.
371 while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData,
372 SPDRP_HARDWAREID,&data, (PBYTE)buffer, buffersize, &buffersize)) {
373 if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
374 if(buffer) free(buffer);
375 // double buffer size to avoid problems as per KB888609
376 buffer = (LPTSTR)malloc(buffersize * 2);
378 else {
379 break;
383 unsigned int vid, pid, rev;
384 if(_stscanf(buffer, _TEXT("USB\\Vid_%x&Pid_%x&Rev_%x"), &vid, &pid, &rev) != 3) {
385 qDebug() << "Error getting USB ID -- possibly no USB device";
387 else {
388 uint32_t id;
389 id = vid << 16 | pid;
390 usbids.append(id);
391 qDebug("VID: %04x PID: %04x", vid, pid);
393 if(buffer) free(buffer);
395 SetupDiDestroyDeviceInfoList(deviceInfo);
397 #endif
398 return usbids;