RabbitCommon v2.2.6
Loading...
Searching...
No Matches
adminauthorization_win.cpp
1
35#include "adminauthorization_p.h"
36
37#include <QtCore/QSettings>
38#include <QtCore/QVariant>
39#include <QtCore/QDir>
40#include <QtCore/qt_windows.h>
41
42using namespace RabbitCommon;
43
44static QString qt_create_commandline(const QStringList &arguments);
45
47{
49 : neededCoInit(CoInitialize(NULL) == S_OK)
50 {}
51
53 {
54 if (neededCoInit)
55 CoUninitialize();
56 }
57 bool neededCoInit;
58};
59
61{
62 SID_IDENTIFIER_AUTHORITY authority = { SECURITY_NT_AUTHORITY };
63 PSID adminGroup;
64 // Initialize SID.
65 if (!AllocateAndInitializeSid(&authority,
66 2,
67 SECURITY_BUILTIN_DOMAIN_RID,
68 DOMAIN_ALIAS_RID_ADMINS,
69 0, 0, 0, 0, 0, 0,
70 &adminGroup))
71 return false;
72
73 BOOL isInAdminGroup = FALSE;
74 if (!CheckTokenMembership(0, adminGroup, &isInAdminGroup))
75 isInAdminGroup = FALSE;
76
77 FreeSid(adminGroup);
78 return (bool)isInAdminGroup;
79}
80
81bool CAdminAuthorization::executeAsAdmin(const QString &program, const QStringList &arguments)
82{
84
85 // AdminAuthorization::execute uses UAC to ask for admin privileges. If the user is no
86 // administrator yet and the computer's policies are set to not use UAC (which is the case
87 // in some corporate networks), the call to execute() will simply succeed and not at all
88 // launch the child process. To avoid this, we detect this situation here and return early.
89 if (!hasAdminRights()) {
90 QLatin1String key("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
91 QSettings registry(key, QSettings::NativeFormat);
92 const QVariant enableLUA = registry.value(QLatin1String("EnableLUA"));
93 if (
94#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
95 (enableLUA.typeId() == QMetaType::Int)
96#else
97 (enableLUA.type() == QVariant::Int)
98#endif
99 && (enableLUA.toInt() == 0))
100 return false;
101 }
102
103 const QString file = QDir::toNativeSeparators(program);
104 const QString args = qt_create_commandline(arguments);
105
106 SHELLEXECUTEINFOW shellExecuteInfo;
107 ZeroMemory(&shellExecuteInfo, sizeof(SHELLEXECUTEINFOW));
108 shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
109 shellExecuteInfo.lpVerb = L"runas";
110 shellExecuteInfo.lpFile = (wchar_t *)file.utf16();
111 shellExecuteInfo.lpParameters = (wchar_t *)args.utf16();
112 shellExecuteInfo.nShow = SW_SHOW;
113
114 if (ShellExecuteExW(&shellExecuteInfo))
115 return true;
116 else
117 return false;
118}
119
120QString qt_create_commandline(const QStringList &arguments)
121{
122 QString args;
123 for (int i = 0; i < arguments.size(); ++i) {
124 QString tmp = arguments.at(i);
125 // in the case of \" already being in the string the \ must also be escaped
126 tmp.replace(QLatin1String("\\\""), QLatin1String("\\\\\""));
127 // escape a single " because the arguments will be parsed
128 tmp.replace(QLatin1Char('\"'), QLatin1String("\\\""));
129 if (tmp.isEmpty() || tmp.contains(QLatin1Char(' ')) || tmp.contains(QLatin1Char('\t'))) {
130 // The argument must not end with a \ since this would be interpreted
131 // as escaping the quote -- rather put the \ behind the quote: e.g.
132 // rather use "foo"\ than "foo\"
133 QString endQuote(QLatin1Char('\"'));
134 int i = tmp.length();
135 while (i > 0 && tmp.at(i - 1) == QLatin1Char('\\')) {
136 --i;
137 endQuote += QLatin1Char('\\');
138 }
139 args += QLatin1String(" \"") + tmp.left(i) + endQuote;
140 } else {
141 args += QLatin1Char(' ') + tmp;
142 }
143 }
144 return args;
145}
bool hasAdminRights() override
Tests whether this program already has elevated rights or not.
bool executeAsAdmin(const QString &program, const QStringList &arguments) override
Runs a program with the given arguments with elevated rights.