diff options
Diffstat (limited to 'rbutil')
-rw-r--r-- | rbutil/rbutilqt/detect.cpp | 409 | ||||
-rw-r--r-- | rbutil/rbutilqt/detect.h | 51 |
2 files changed, 460 insertions, 0 deletions
diff --git a/rbutil/rbutilqt/detect.cpp b/rbutil/rbutilqt/detect.cpp new file mode 100644 index 0000000000..95dee307b2 --- /dev/null +++ b/rbutil/rbutilqt/detect.cpp | |||
@@ -0,0 +1,409 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2007 by Dominik Wenger | ||
10 | * $Id: detect.cpp 17769 2008-06-23 20:31:44Z Domonoky $ | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | |||
21 | #include "detect.h" | ||
22 | |||
23 | #include <QtCore> | ||
24 | #include <QDebug> | ||
25 | #include <cstdlib> | ||
26 | #include <stdio.h> | ||
27 | #include <QMessageBox> | ||
28 | |||
29 | |||
30 | // Windows Includes | ||
31 | #if defined(Q_OS_WIN32) | ||
32 | #if defined(UNICODE) | ||
33 | #define _UNICODE | ||
34 | #endif | ||
35 | #include <windows.h> | ||
36 | #include <tchar.h> | ||
37 | #include <lm.h> | ||
38 | #include <windows.h> | ||
39 | #include <setupapi.h> | ||
40 | #endif | ||
41 | |||
42 | // Linux and Mac includes | ||
43 | #if defined(Q_OS_LINUX) || defined(Q_OS_MACX) | ||
44 | #include <usb.h> | ||
45 | #include <sys/utsname.h> | ||
46 | #include <unistd.h> | ||
47 | #include <pwd.h> | ||
48 | #endif | ||
49 | |||
50 | // Linux includes | ||
51 | #if defined(Q_OS_LINUX) | ||
52 | #include <mntent.h> | ||
53 | #endif | ||
54 | |||
55 | // Mac includes | ||
56 | #if defined(Q_OS_MACX) | ||
57 | #include <sys/param.h> | ||
58 | #include <sys/ucred.h> | ||
59 | #include <sys/mount.h> | ||
60 | #endif | ||
61 | |||
62 | |||
63 | /** @brief detect permission of user (only Windows at moment). | ||
64 | * @return enum userlevel. | ||
65 | */ | ||
66 | #if defined(Q_OS_WIN32) | ||
67 | enum userlevel Detect::userPermissions(void) | ||
68 | { | ||
69 | LPUSER_INFO_1 buf; | ||
70 | NET_API_STATUS napistatus; | ||
71 | wchar_t userbuf[UNLEN]; | ||
72 | DWORD usersize = UNLEN; | ||
73 | BOOL status; | ||
74 | enum userlevel result; | ||
75 | |||
76 | status = GetUserNameW(userbuf, &usersize); | ||
77 | if(!status) | ||
78 | return ERR; | ||
79 | |||
80 | napistatus = NetUserGetInfo(NULL, userbuf, (DWORD)1, (LPBYTE*)&buf); | ||
81 | |||
82 | switch(buf->usri1_priv) { | ||
83 | case USER_PRIV_GUEST: | ||
84 | result = GUEST; | ||
85 | break; | ||
86 | case USER_PRIV_USER: | ||
87 | result = USER; | ||
88 | break; | ||
89 | case USER_PRIV_ADMIN: | ||
90 | result = ADMIN; | ||
91 | break; | ||
92 | default: | ||
93 | result = ERR; | ||
94 | break; | ||
95 | } | ||
96 | NetApiBufferFree(buf); | ||
97 | |||
98 | return result; | ||
99 | } | ||
100 | |||
101 | /** @brief detects user permissions (only Windows at moment). | ||
102 | * @return a user readable string with the permission. | ||
103 | */ | ||
104 | QString Detect::userPermissionsString(void) | ||
105 | { | ||
106 | QString result; | ||
107 | int perm = getUserPermissions(); | ||
108 | switch(perm) { | ||
109 | case GUEST: | ||
110 | result = QObject::tr("Guest"); | ||
111 | break; | ||
112 | case ADMIN: | ||
113 | result = QObject::tr("Admin"); | ||
114 | break; | ||
115 | case USER: | ||
116 | result = QObject::tr("User"); | ||
117 | break; | ||
118 | default: | ||
119 | result = QObject::tr("Error"); | ||
120 | break; | ||
121 | } | ||
122 | return result; | ||
123 | } | ||
124 | #endif | ||
125 | |||
126 | |||
127 | /** @brief detects current Username. | ||
128 | * @return string with Username. | ||
129 | */ | ||
130 | QString Detect::userName(void) | ||
131 | { | ||
132 | #if defined(Q_OS_WIN32) | ||
133 | wchar_t userbuf[UNLEN]; | ||
134 | DWORD usersize = UNLEN; | ||
135 | BOOL status; | ||
136 | |||
137 | status = GetUserNameW(userbuf, &usersize); | ||
138 | |||
139 | return QString::fromWCharArray(userbuf); | ||
140 | #endif | ||
141 | #if defined(Q_OS_LINUX) || defined(Q_OS_MACX) | ||
142 | struct passwd *user; | ||
143 | user = getpwuid(geteuid()); | ||
144 | return QString(user->pw_name); | ||
145 | #endif | ||
146 | } | ||
147 | |||
148 | |||
149 | /** @brief detects the OS Version | ||
150 | * @return String with OS Version. | ||
151 | */ | ||
152 | QString Detect::osVersionString(void) | ||
153 | { | ||
154 | QString result; | ||
155 | #if defined(Q_OS_WIN32) | ||
156 | OSVERSIONINFO osvi; | ||
157 | ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); | ||
158 | osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); | ||
159 | GetVersionEx(&osvi); | ||
160 | |||
161 | result = QString("Windows version %1.%2, ").arg(osvi.dwMajorVersion).arg(osvi.dwMinorVersion); | ||
162 | result += QString("build %1 (%2)").arg(osvi.dwBuildNumber).arg(QString::fromWCharArray(osvi.szCSDVersion)); | ||
163 | #endif | ||
164 | #if defined(Q_OS_LINUX) || defined(Q_OS_MACX) | ||
165 | struct utsname u; | ||
166 | int ret; | ||
167 | ret = uname(&u); | ||
168 | |||
169 | result = QString("CPU: %1<br/>System: %2<br/>Release: %3<br/>Version: %4") | ||
170 | .arg(u.machine).arg(u.sysname).arg(u.release).arg(u.version); | ||
171 | #endif | ||
172 | return result; | ||
173 | } | ||
174 | |||
175 | /** @brief detect devices based on usb pid / vid. | ||
176 | * @return list with usb VID / PID values. | ||
177 | */ | ||
178 | QList<uint32_t> Detect::listUsbIds(void) | ||
179 | { | ||
180 | QList<uint32_t> usbids; | ||
181 | // usb pid detection | ||
182 | #if defined(Q_OS_LINUX) | defined(Q_OS_MACX) | ||
183 | usb_init(); | ||
184 | usb_find_busses(); | ||
185 | usb_find_devices(); | ||
186 | struct usb_bus *b; | ||
187 | b = usb_busses; | ||
188 | |||
189 | while(b) { | ||
190 | qDebug() << "bus:" << b->dirname << b->devices; | ||
191 | if(b->devices) { | ||
192 | qDebug() << "devices present."; | ||
193 | struct usb_device *u; | ||
194 | u = b->devices; | ||
195 | while(u) { | ||
196 | uint32_t id; | ||
197 | id = u->descriptor.idVendor << 16 | u->descriptor.idProduct; | ||
198 | if(id) usbids.append(id); | ||
199 | u = u->next; | ||
200 | } | ||
201 | } | ||
202 | b = b->next; | ||
203 | } | ||
204 | #endif | ||
205 | |||
206 | #if defined(Q_OS_WIN32) | ||
207 | HDEVINFO deviceInfo; | ||
208 | SP_DEVINFO_DATA infoData; | ||
209 | DWORD i; | ||
210 | |||
211 | // Iterate over all devices | ||
212 | // by doing it this way it's unneccessary to use GUIDs which might be not | ||
213 | // present in current MinGW. It also seemed to be more reliably than using | ||
214 | // a GUID. | ||
215 | // See KB259695 for an example. | ||
216 | deviceInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT); | ||
217 | |||
218 | infoData.cbSize = sizeof(SP_DEVINFO_DATA); | ||
219 | |||
220 | for(i = 0; SetupDiEnumDeviceInfo(deviceInfo, i, &infoData); i++) { | ||
221 | DWORD data; | ||
222 | LPTSTR buffer = NULL; | ||
223 | DWORD buffersize = 0; | ||
224 | |||
225 | // get device desriptor first | ||
226 | // for some reason not doing so results in bad things (tm) | ||
227 | while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData, | ||
228 | SPDRP_DEVICEDESC,&data, (PBYTE)buffer, buffersize, &buffersize)) { | ||
229 | if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { | ||
230 | if(buffer) free(buffer); | ||
231 | // double buffer size to avoid problems as per KB888609 | ||
232 | buffer = (LPTSTR)malloc(buffersize * 2); | ||
233 | } | ||
234 | else { | ||
235 | break; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | // now get the hardware id, which contains PID and VID. | ||
240 | while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData, | ||
241 | SPDRP_HARDWAREID,&data, (PBYTE)buffer, buffersize, &buffersize)) { | ||
242 | if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { | ||
243 | if(buffer) free(buffer); | ||
244 | // double buffer size to avoid problems as per KB888609 | ||
245 | buffer = (LPTSTR)malloc(buffersize * 2); | ||
246 | } | ||
247 | else { | ||
248 | break; | ||
249 | } | ||
250 | } | ||
251 | |||
252 | unsigned int vid, pid, rev; | ||
253 | if(_stscanf(buffer, _TEXT("USB\\Vid_%x&Pid_%x&Rev_%x"), &vid, &pid, &rev) != 3) { | ||
254 | qDebug() << "Error getting USB ID -- possibly no USB device"; | ||
255 | } | ||
256 | else { | ||
257 | uint32_t id; | ||
258 | id = vid << 16 | pid; | ||
259 | usbids.append(id); | ||
260 | qDebug("VID: %04x PID: %04x", vid, pid); | ||
261 | } | ||
262 | if(buffer) free(buffer); | ||
263 | } | ||
264 | SetupDiDestroyDeviceInfoList(deviceInfo); | ||
265 | |||
266 | #endif | ||
267 | return usbids; | ||
268 | } | ||
269 | |||
270 | |||
271 | /** @brief detects current system proxy | ||
272 | * @return QUrl with proxy or empty | ||
273 | */ | ||
274 | QUrl Detect::systemProxy(void) | ||
275 | { | ||
276 | #if defined(Q_OS_LINUX) | ||
277 | return QUrl(getenv("http_proxy")); | ||
278 | #elif defined(Q_OS_WIN32) | ||
279 | HKEY hk; | ||
280 | wchar_t proxyval[80]; | ||
281 | DWORD buflen = 80; | ||
282 | long ret; | ||
283 | DWORD enable; | ||
284 | DWORD enalen = sizeof(DWORD); | ||
285 | |||
286 | ret = RegOpenKeyEx(HKEY_CURRENT_USER, | ||
287 | _TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"), | ||
288 | 0, KEY_QUERY_VALUE, &hk); | ||
289 | if(ret != ERROR_SUCCESS) return QUrl(""); | ||
290 | |||
291 | ret = RegQueryValueEx(hk, _TEXT("ProxyServer"), NULL, NULL, (LPBYTE)proxyval, &buflen); | ||
292 | if(ret != ERROR_SUCCESS) return QUrl(""); | ||
293 | |||
294 | ret = RegQueryValueEx(hk, _TEXT("ProxyEnable"), NULL, NULL, (LPBYTE)&enable, &enalen); | ||
295 | if(ret != ERROR_SUCCESS) return QUrl(""); | ||
296 | |||
297 | RegCloseKey(hk); | ||
298 | |||
299 | //qDebug() << QString::fromWCharArray(proxyval) << QString("%1").arg(enable); | ||
300 | if(enable != 0) | ||
301 | return QUrl("http://" + QString::fromWCharArray(proxyval)); | ||
302 | else | ||
303 | return QUrl(""); | ||
304 | #else | ||
305 | return QUrl(""); | ||
306 | #endif | ||
307 | } | ||
308 | |||
309 | |||
310 | /** @brief detects the installed Rockbox version | ||
311 | * @return QString with version. Empty if not aviable | ||
312 | */ | ||
313 | QString Detect::installedVersion(QString mountpoint) | ||
314 | { | ||
315 | // read rockbox-info.txt | ||
316 | QFile info(mountpoint +"/.rockbox/rockbox-info.txt"); | ||
317 | if(!info.open(QIODevice::ReadOnly)) | ||
318 | { | ||
319 | return ""; | ||
320 | } | ||
321 | |||
322 | while (!info.atEnd()) { | ||
323 | QString line = info.readLine(); | ||
324 | |||
325 | if(line.contains("Version:")) | ||
326 | { | ||
327 | return line.remove("Version:").trimmed(); | ||
328 | } | ||
329 | } | ||
330 | info.close(); | ||
331 | return ""; | ||
332 | } | ||
333 | |||
334 | |||
335 | /** @brief detects installed rockbox target id | ||
336 | * @return TargetId of installed rockbox, or -1 if not available | ||
337 | */ | ||
338 | int Detect::installedTargetId(QString mountpoint) | ||
339 | { | ||
340 | // read rockbox-info.txt | ||
341 | QFile info(mountpoint +"/.rockbox/rockbox-info.txt"); | ||
342 | if(!info.open(QIODevice::ReadOnly)) | ||
343 | { | ||
344 | return -1; | ||
345 | } | ||
346 | |||
347 | while (!info.atEnd()) | ||
348 | { | ||
349 | QString line = info.readLine(); | ||
350 | if(line.contains("Target id:")) | ||
351 | { | ||
352 | qDebug() << line; | ||
353 | return line.remove("Target id:").trimmed().toInt(); | ||
354 | } | ||
355 | } | ||
356 | info.close(); | ||
357 | return -1; | ||
358 | } | ||
359 | |||
360 | |||
361 | /** @brief checks different Enviroment things. Ask if user wants to continue. | ||
362 | * @param settings A pointer to rbutils settings class | ||
363 | * @param permission if it should check for permission | ||
364 | * @param targetId the targetID to check for. if it is -1 no check is done. | ||
365 | * @return true if everything is ok, or user wants to continue | ||
366 | */ | ||
367 | bool Detect::check(RbSettings* settings,bool permission,int targetId) | ||
368 | { | ||
369 | QString text = ""; | ||
370 | |||
371 | // check permission | ||
372 | if(permission) | ||
373 | { | ||
374 | #if defined(Q_OS_WIN32) | ||
375 | if(Detect::userPermissions() != Detect::ADMIN) | ||
376 | { | ||
377 | text += QObject::tr("Permissions are not sufficient! \n Run with admin rights. \n\n"); | ||
378 | } | ||
379 | #endif | ||
380 | } | ||
381 | |||
382 | // Check TargetId | ||
383 | if(targetId > 0) | ||
384 | { | ||
385 | int installedID = Detect::installedTargetId(settings->mountpoint()); | ||
386 | if( installedID != -1 && installedID != targetId) | ||
387 | { | ||
388 | text += QObject::tr("Target mismatch detected. \n\n" | ||
389 | "Installed target: %1.\n" | ||
390 | "New Target: %2.\n\n").arg(settings->nameOfTargetId(installedID),settings->curName()); | ||
391 | |||
392 | } | ||
393 | } | ||
394 | |||
395 | // show message Box | ||
396 | if(text != "") | ||
397 | { | ||
398 | text += QObject::tr("\n Do you want to continue ?"); | ||
399 | if(QMessageBox::warning(NULL, QObject::tr("Problems detected"),text, | ||
400 | QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) | ||
401 | { | ||
402 | return false; | ||
403 | } | ||
404 | } | ||
405 | |||
406 | return true; | ||
407 | } | ||
408 | |||
409 | |||
diff --git a/rbutil/rbutilqt/detect.h b/rbutil/rbutilqt/detect.h new file mode 100644 index 0000000000..98d6040ac0 --- /dev/null +++ b/rbutil/rbutilqt/detect.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2007 by Dominik Wenger | ||
10 | * $Id: detect.h 17769 2008-06-23 20:31:44Z Domonoky $ | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | |||
21 | #ifndef DETECT_H | ||
22 | #define DETECT_H | ||
23 | |||
24 | #include <QString> | ||
25 | #include <QUrl> | ||
26 | #include "rbsettings.h" | ||
27 | |||
28 | class Detect | ||
29 | { | ||
30 | public: | ||
31 | Detect() {} | ||
32 | |||
33 | #if defined(Q_OS_WIN32) | ||
34 | enum userlevel { ERR, GUEST, USER, ADMIN }; | ||
35 | static enum userlevel userPermissions(void); | ||
36 | static QString userPermissionsString(void); | ||
37 | #endif | ||
38 | |||
39 | static QString userName(void); | ||
40 | static QString osVersionString(void); | ||
41 | static QList<uint32_t> listUsbIds(void); | ||
42 | |||
43 | static QUrl systemProxy(void); | ||
44 | static QString installedVersion(QString mountpoint); | ||
45 | static int installedTargetId(QString mountpoint); | ||
46 | |||
47 | static bool check(RbSettings* settings,bool permission,int targetId); | ||
48 | |||
49 | #endif | ||
50 | }; | ||
51 | |||