main.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /*
  2. main.cpp from UNetbootin <http://unetbootin.sourceforge.net>
  3. Copyright (C) 2007-2008 Geza Kovacs <geza0kovacs@gmail.com>
  4. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.
  5. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at <http://www.gnu.org/licenses/> for more details.
  6. */
  7. #include "unetbootin.h"
  8. #ifdef Q_OS_WIN32
  9. void configsysUndo(QString uninstPathL)
  10. {
  11. if (!QFile::copy(QDir::toNativeSeparators(QString("%1unetbtin/config.sys").arg(uninstPathL)), QDir::toNativeSeparators(QString("%1config.sys").arg(uninstPathL))))
  12. {
  13. QFile::remove(QDir::toNativeSeparators(QString("%1config.sys").arg(uninstPathL)));
  14. QFile::copy(QDir::toNativeSeparators(QString("%1unetbtin/config.sys").arg(uninstPathL)), QDir::toNativeSeparators(QString("%1config.sys").arg(uninstPathL)));
  15. }
  16. SetFileAttributesA(QDir::toNativeSeparators(QString("%1config.sys").arg(uninstPathL)).toLocal8Bit(), FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE);
  17. }
  18. void bootiniUndo(QString uninstPathL)
  19. {
  20. if (!QFile::copy(QDir::toNativeSeparators(QString("%1unetbtin/boot.ini").arg(uninstPathL)), QDir::toNativeSeparators(QString("%1boot.ini").arg(uninstPathL))))
  21. {
  22. QFile::remove(QDir::toNativeSeparators(QString("%1boot.ini").arg(uninstPathL)));
  23. QFile::copy(QDir::toNativeSeparators(QString("%1unetbtin/boot.ini").arg(uninstPathL)), QDir::toNativeSeparators(QString("%1boot.ini").arg(uninstPathL)));
  24. }
  25. SetFileAttributesW(LPWSTR(QDir::toNativeSeparators(QString("%1boot.ini").arg(uninstPathL)).utf16()), FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE);
  26. }
  27. void vistabcdUndo(QString uninstPathL)
  28. {
  29. QSettings vdtustor("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\UNetbootin", QSettings::NativeFormat);
  30. QVariant warch64varL(QVariant::Bool);
  31. warch64varL = vdtustor.value("WArch64");
  32. bool warch64L = warch64varL.value<bool>();
  33. if (warch64L)
  34. {
  35. unetbootin::callexternapp(QDir::toNativeSeparators(QString("%1unetbtin/emtxfile.exe").arg(uninstPathL)), QDir::toNativeSeparators(QString("%1unetbtin/vbcdundo.bat runas").arg(uninstPathL)));
  36. }
  37. else
  38. {
  39. unetbootin::callexternapp(QDir::toNativeSeparators(QString("%1unetbtin/vbcdundo.bat").arg(uninstPathL)), "");
  40. }
  41. vdtustor.remove("WArch64");
  42. }
  43. #endif
  44. void clearOutDir(QString pDirToDel)
  45. {
  46. QDir dirToDel(pDirToDel);
  47. QStringList rmfileList = dirToDel.entryList(QDir::Files);
  48. for (int i = 0; i < rmfileList.size(); ++i)
  49. {
  50. QFile::setPermissions(QDir::toNativeSeparators(QString("%1/%2").arg(pDirToDel).arg(rmfileList.at(i))), QFile::WriteOther);
  51. QFile::remove(QDir::toNativeSeparators(QString("%1/%2").arg(pDirToDel).arg(rmfileList.at(i))));
  52. }
  53. dirToDel.rmdir(pDirToDel);
  54. }
  55. void ubnUninst()
  56. {
  57. #ifdef Q_OS_UNIX
  58. QSettings chkinstL(QSettings::SystemScope, "UNetbootin");
  59. QString uninstPath = "/";
  60. QString uninstsubDir = QDir::toNativeSeparators(QString("%1boot/").arg(uninstPath));
  61. if (QFile::exists(QString("%1ubninit").arg(uninstsubDir)))
  62. QFile::remove(QString("%1ubninit").arg(uninstsubDir));
  63. if (QFile::exists(QString("%1ubnkern").arg(uninstsubDir)))
  64. QFile::remove(QString("%1ubnkern").arg(uninstsubDir));
  65. if (QFile::exists(QString("%1grub/menu.lst.bak").arg(uninstsubDir)))
  66. {
  67. if (QFile::exists(QString("%1grub/menu.lst").arg(uninstsubDir)))
  68. {
  69. QFile::remove(QString("%1grub/menu.lst").arg(uninstsubDir));
  70. }
  71. QFile::rename(QString("%1grub/menu.lst.bak").arg(uninstsubDir), QString("%1grub/menu.lst").arg(uninstsubDir));
  72. }
  73. if (QFile::exists(QString("%1grub/grub.cfg.bak").arg(uninstsubDir)))
  74. {
  75. if (QFile::exists(QString("%1grub/grub.cfg").arg(uninstsubDir)))
  76. {
  77. QFile::remove(QString("%1grub/grub.cfg").arg(uninstsubDir));
  78. }
  79. QFile::rename(QString("%1grub/grub.cfg.bak").arg(uninstsubDir), QString("%1grub/grub.cfg").arg(uninstsubDir));
  80. }
  81. #endif
  82. #ifdef Q_OS_WIN32
  83. QSettings autostrt("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce", QSettings::NativeFormat);
  84. if (autostrt.contains("UNetbootin Uninstaller"))
  85. {
  86. autostrt.remove("UNetbootin Uninstaller");
  87. }
  88. QSettings chkinstL("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\UNetbootin", QSettings::NativeFormat);
  89. QVariant uninstvar(QVariant::String);
  90. uninstvar = chkinstL.value("Location");
  91. QString uninstPath = uninstvar.value<QString>();
  92. QString uninstsubDir = QDir::toNativeSeparators(QString("%1unetbtin/").arg(uninstPath));
  93. if (QSysInfo::WindowsVersion == QSysInfo::WV_32s || QSysInfo::WindowsVersion == QSysInfo::WV_95 || QSysInfo::WindowsVersion == QSysInfo::WV_98 || QSysInfo::WindowsVersion == QSysInfo::WV_Me)
  94. {
  95. configsysUndo(uninstPath);
  96. }
  97. else if (QSysInfo::WindowsVersion == QSysInfo::WV_NT || QSysInfo::WindowsVersion == QSysInfo::WV_2000 || QSysInfo::WindowsVersion == QSysInfo::WV_XP || QSysInfo::WindowsVersion == QSysInfo::WV_2003 )
  98. {
  99. bootiniUndo(uninstPath);
  100. }
  101. else if (QSysInfo::WindowsVersion == QSysInfo::WV_VISTA)
  102. {
  103. vistabcdUndo(uninstPath);
  104. }
  105. else
  106. {
  107. configsysUndo(uninstPath);
  108. bootiniUndo(uninstPath);
  109. vistabcdUndo(uninstPath);
  110. }
  111. #endif
  112. if (QFile::exists(QString("%1ubnfilel.txt").arg(uninstsubDir)))
  113. {
  114. QFile ubnfilelF(QString("%1ubnfilel.txt").arg(uninstsubDir));
  115. ubnfilelF.open(QIODevice::ReadOnly | QIODevice::Text);
  116. QTextStream ubnfilelS(&ubnfilelF);
  117. while (!ubnfilelS.atEnd())
  118. {
  119. QFile::remove(QString("%1%2").arg(uninstPath).arg(ubnfilelS.readLine()));
  120. }
  121. ubnfilelF.close();
  122. QFile::remove(QString("%1ubnfilel.txt").arg(uninstsubDir));
  123. }
  124. if (QFile::exists(QString("%1ubnpathl.txt").arg(uninstsubDir)))
  125. {
  126. QFile ubnpathlF(QString("%1ubnpathl.txt").arg(uninstsubDir));
  127. ubnpathlF.open(QIODevice::ReadOnly | QIODevice::Text);
  128. QTextStream ubnpathlS(&ubnpathlF);
  129. QDir unrdir(uninstPath);
  130. while (!ubnpathlS.atEnd())
  131. {
  132. unrdir.rmdir(ubnpathlS.readLine());
  133. }
  134. ubnpathlF.close();
  135. QFile::remove(QString("%1ubnpathl.txt").arg(uninstsubDir));
  136. }
  137. #ifdef Q_OS_WIN32
  138. clearOutDir(QDir::toNativeSeparators(QString("%1unetbtin").arg(uninstPath)));
  139. QFile::remove(QDir::toNativeSeparators(QString("%1ubnldr.exe").arg(uninstPath)));
  140. QFile::remove(QDir::toNativeSeparators(QString("%1ubnldr").arg(uninstPath)));
  141. QFile::remove(QDir::toNativeSeparators(QString("%1ubnldr.mbr").arg(uninstPath)));
  142. #endif
  143. chkinstL.clear();
  144. QMessageBox finmsgb;
  145. finmsgb.setIcon(QMessageBox::Information);
  146. finmsgb.setWindowTitle(uninstaller::tr("Uninstallation Complete"));
  147. finmsgb.setText(uninstaller::tr("%1 has been uninstalled.").arg(UNETBOOTINB));
  148. finmsgb.setStandardButtons(QMessageBox::Ok);
  149. switch (finmsgb.exec())
  150. {
  151. case QMessageBox::Ok:
  152. break;
  153. default:
  154. break;
  155. }
  156. }
  157. QString checkforgraphicalsu(QString graphicalsu)
  158. {
  159. QProcess whereiscommand;
  160. whereiscommand.start(QString("which %1").arg(graphicalsu));
  161. whereiscommand.waitForFinished(-1);
  162. QString commandbinpath = QString(whereiscommand.readAll()).trimmed();
  163. if (!commandbinpath.isEmpty() && QFile::exists(commandbinpath))
  164. return commandbinpath;
  165. else
  166. return "REQCNOTFOUND";
  167. }
  168. int main(int argc, char **argv)
  169. {
  170. QApplication app(argc, argv, true);
  171. QTranslator custranldr;
  172. QTranslator translator;
  173. QString tnapplang;
  174. QString tnappcoun;
  175. QString clangcode = "";
  176. QStringList allappargs = app.arguments();
  177. QList<QPair<QString, QString> > oppairs;
  178. for (QList<QString>::const_iterator i = allappargs.constBegin(); i < allappargs.constEnd(); ++i)
  179. {
  180. if (i->count('=') == 1)
  181. oppairs.append(QPair<QString, QString>(i->section('=', 0, 0).simplified(), i->section('=',1, 1).simplified()));
  182. }
  183. for (QList<QPair<QString, QString> >::const_iterator i = oppairs.constBegin(); i < oppairs.constEnd(); ++i)
  184. {
  185. if (i->first.contains("lang", Qt::CaseInsensitive))
  186. {
  187. clangcode = i->second;
  188. tnapplang = clangcode.left(2);
  189. if (clangcode.contains('_') && clangcode.size() == 5)
  190. {
  191. tnappcoun = clangcode.section('_', -1, -1);
  192. }
  193. break;
  194. }
  195. }
  196. if (clangcode.isEmpty())
  197. {
  198. clangcode = QLocale::system().name();
  199. tnapplang = clangcode.left(2);
  200. if (clangcode.contains('_') && clangcode.size() == 5)
  201. {
  202. tnappcoun = clangcode.section('_', -1, -1);
  203. }
  204. }
  205. QDir applocdir(app.applicationDirPath());
  206. QStringList applocfiles = applocdir.entryList(QStringList() << "*.qm", QDir::Files);
  207. if (!applocfiles.isEmpty())
  208. {
  209. QString custqmfilepath = applocfiles.at(0);
  210. if (!applocfiles.filter("unetbootin").isEmpty())
  211. {
  212. custqmfilepath = applocfiles.filter("unetbootin").at(0);
  213. if (!applocfiles.filter("unetbootin").filter(tnapplang).isEmpty())
  214. {
  215. custqmfilepath = applocfiles.filter("unetbootin").filter(tnapplang).at(0);
  216. if (!tnappcoun.isEmpty() && !applocfiles.filter("unetbootin").filter(tnapplang).filter(tnappcoun).isEmpty())
  217. custqmfilepath = applocfiles.filter("unetbootin").filter(tnapplang).filter(tnappcoun).at(0);
  218. }
  219. }
  220. if (custranldr.load(custqmfilepath, app.applicationDirPath()))
  221. app.installTranslator(&custranldr);
  222. }
  223. if (!tnappcoun.isEmpty() && QFile::exists(QString("%1/unetbootin_%2_%3.qm").arg(app.applicationDirPath()).arg(tnapplang).arg(tnappcoun)) && translator.load(QString("%1/unetbootin_%2_%3.qm").arg(app.applicationDirPath()).arg(tnapplang).arg(tnappcoun)))
  224. {
  225. app.installTranslator(&translator);
  226. }
  227. else if (!tnappcoun.isEmpty() && QFile::exists(QString(":/unetbootin_%1_%2.qm").arg(tnapplang).arg(tnappcoun)) && translator.load(QString(":/unetbootin_%1_%2.qm").arg(tnapplang).arg(tnappcoun)))
  228. {
  229. app.installTranslator(&translator);
  230. }
  231. else if (!tnappcoun.isEmpty() && QFile::exists(QString("/usr/share/unetbootin/unetbootin_%1_%2.qm").arg(tnapplang).arg(tnappcoun)) && translator.load(QString("/usr/share/unetbootin/unetbootin_%1_%2.qm").arg(tnapplang).arg(tnappcoun)))
  232. {
  233. app.installTranslator(&translator);
  234. }
  235. else if (QFile::exists(QString("%1/unetbootin_%2.qm").arg(app.applicationDirPath(), tnapplang)) && translator.load(QString("%1/unetbootin_%2.qm").arg(app.applicationDirPath(), tnapplang)))
  236. {
  237. app.installTranslator(&translator);
  238. }
  239. else if (QFile::exists(QString(":/unetbootin_%1.qm").arg(tnapplang)) && translator.load(QString(":/unetbootin_%1.qm").arg(tnapplang)))
  240. {
  241. app.installTranslator(&translator);
  242. }
  243. else if (QFile::exists(QString("/usr/share/unetbootin/unetbootin_%1.qm").arg(tnapplang)) && translator.load(QString("/usr/share/unetbootin/unetbootin_%1.qm").arg(tnapplang)))
  244. {
  245. app.installTranslator(&translator);
  246. }
  247. else
  248. {
  249. tnapplang = "en";
  250. tnappcoun = "US";
  251. clangcode = "en_US";
  252. }
  253. app.installTranslator(&translator);
  254. if (QObject::tr("LeftToRight") == "RightToLeft")
  255. app.setLayoutDirection(Qt::RightToLeft);
  256. #ifdef Q_OS_UNIX
  257. bool disabledrootcheck = false;
  258. for (QList<QPair<QString, QString> >::const_iterator i = oppairs.constBegin(); i < oppairs.constEnd(); ++i)
  259. {
  260. if (i->first.contains("rootcheck", Qt::CaseInsensitive))
  261. {
  262. if (i->second.contains('n', Qt::CaseInsensitive))
  263. disabledrootcheck = true;
  264. break;
  265. }
  266. }
  267. if (!disabledrootcheck)
  268. {
  269. QProcess whoamip;
  270. whoamip.start("whoami");
  271. whoamip.waitForFinished();
  272. if (QString(whoamip.readAll()).remove("\r").remove("\n") != "root")
  273. {
  274. QString argsconc = "";
  275. QString argsconcSingleQuote = "";
  276. for (int i = 1; i < allappargs.size(); ++i)
  277. {
  278. argsconc += QString("\"%1\" ").arg(allappargs.at(i));
  279. argsconcSingleQuote += QString("'%1' ").arg(allappargs.at(i));
  280. }
  281. argsconc += "\"rootcheck=no\"";
  282. argsconcSingleQuote += "'rootcheck=no'";
  283. #ifdef Q_OS_LINUX
  284. QString gksulocation = checkforgraphicalsu("gksu");
  285. if (gksulocation != "REQCNOTFOUND")
  286. {
  287. QProcess::startDetached(QString("%1 %2 %3").arg(gksulocation).arg(app.applicationFilePath()).arg(argsconc));
  288. return 0;
  289. }
  290. QString kdesulocation = checkforgraphicalsu("kdesu");
  291. if (kdesulocation != "REQCNOTFOUND")
  292. {
  293. QProcess::startDetached(QString("%1 %2 %3").arg(kdesulocation).arg(app.applicationFilePath()).arg(argsconc));
  294. return 0;
  295. }
  296. QString gnomesulocation = checkforgraphicalsu("gnomesu");
  297. if (gnomesulocation != "REQCNOTFOUND")
  298. {
  299. QProcess::startDetached(QString("%1 %2 %3").arg(gnomesulocation).arg(app.applicationFilePath()).arg(argsconc));
  300. return 0;
  301. }
  302. QString kdesudolocation = checkforgraphicalsu("kdesudo");
  303. if (kdesudolocation != "REQCNOTFOUND")
  304. {
  305. QProcess::startDetached(QString("%1 %2 %3").arg(kdesudolocation).arg(app.applicationFilePath()).arg(argsconc));
  306. return 0;
  307. }
  308. QMessageBox rootmsgb;
  309. rootmsgb.setIcon(QMessageBox::Warning);
  310. rootmsgb.setWindowTitle(uninstaller::tr("Must run as root"));
  311. rootmsgb.setTextFormat(Qt::RichText);
  312. rootmsgb.setText(uninstaller::tr("%2 must be run as root. Close it, and re-run using either:<br/><b>sudo %1</b><br/>or:<br/><b>su - -c '%1'</b>").arg(app.applicationFilePath()).arg(UNETBOOTINB));
  313. rootmsgb.setStandardButtons(QMessageBox::Ok);
  314. switch (rootmsgb.exec())
  315. {
  316. case QMessageBox::Ok:
  317. break;
  318. default:
  319. break;
  320. }
  321. #endif
  322. #ifdef Q_OS_MAC
  323. /*
  324. QProcess osascriptProc;
  325. osascriptProc.start("osascript");
  326. osascriptProc.write(QString("do shell script \""+app.applicationFilePath()+"\" with administrator privileges\n").toAscii().data());
  327. osascriptProc.closeWriteChannel();
  328. osascriptProc.waitForFinished(-1);
  329. */
  330. //qDebug() << QString("osascript -e 'do shell script \"%1 %2\" with administrator privileges'").arg(app.applicationFilePath()).arg(argsconc);
  331. //QProcess::startDetached(QString("osascript -e 'do shell script \"%1 %2\" with administrator privileges'").arg(app.applicationFilePath()).arg(argsconc));
  332. QProcess::startDetached("osascript", QStringList() << "-e" << QString("do shell script \"'%1' %2\" with administrator privileges").arg(app.applicationFilePath()).arg(argsconcSingleQuote));
  333. return 0;
  334. #endif
  335. }
  336. }
  337. #endif
  338. #ifdef Q_OS_WIN32
  339. QSettings chkinst("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\UNetbootin", QSettings::NativeFormat);
  340. #endif
  341. #ifdef Q_OS_LINUX
  342. QSettings chkinst(QSettings::SystemScope, "UNetbootin");
  343. #endif
  344. #ifndef Q_OS_MAC
  345. if (chkinst.contains("Location"))
  346. {
  347. QMessageBox uninstmsgb;
  348. uninstmsgb.setIcon(QMessageBox::Information);
  349. uninstmsgb.setWindowTitle(uninstaller::tr("%1 Uninstaller").arg(UNETBOOTINB));
  350. uninstmsgb.setText(uninstaller::tr("%1 is currently installed. Remove the existing version?").arg(UNETBOOTINB));
  351. uninstmsgb.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
  352. switch (uninstmsgb.exec())
  353. {
  354. case QMessageBox::Ok:
  355. {
  356. ubnUninst();
  357. }
  358. case QMessageBox::Cancel:
  359. break;
  360. default:
  361. break;
  362. }
  363. return 0;
  364. }
  365. #endif
  366. unetbootin unetbootin;
  367. unetbootin.appNlang = tnapplang;
  368. unetbootin.appDir = QDir::toNativeSeparators(QString("%1/").arg(app.applicationDirPath()));
  369. unetbootin.appLoc = app.applicationFilePath();
  370. QIcon icon;
  371. icon.addFile(":/unetbootin_16.png", QSize(16,16));
  372. icon.addFile(":/unetbootin_22.png", QSize(22,22));
  373. icon.addFile(":/unetbootin_24.png", QSize(24,24));
  374. icon.addFile(":/unetbootin_32.png", QSize(32,32));
  375. icon.addFile(":/unetbootin_48.png", QSize(48,48));
  376. #ifdef Q_OS_LINUX
  377. //icon.addFile("/usr/share/pixmaps/unetbootin.png");
  378. //icon.addFile("/usr/share/pixmaps/unetbootin.xpm");
  379. icon.addFile("./unetbootin.xpm");
  380. #endif
  381. unetbootin.setWindowIcon(icon);
  382. QObject::connect(&app, SIGNAL(lastWindowClosed()), &unetbootin, SLOT(killApplication()));
  383. bool automate = unetbootin.ubninitialize(oppairs);
  384. unetbootin.show();
  385. if (automate)
  386. QTimer::singleShot(0, &unetbootin, SLOT(on_okbutton_clicked()));
  387. return app.exec();
  388. }