fix logic
[personal-kdelibs.git] / kdecore / util / kuser_win.cpp
blob08de03a39ef62c7d00bbfd8fbd001aa8f92fe169
1 /*
2 * KUser - represent a user/account (Windows)
3 * Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
21 #include "kuser.h"
23 #include <QtCore/QMutableStringListIterator>
24 #include <QtCore/QDir>
26 #include <windows.h>
27 #include <lm.h>
28 #include <userenv.h>
30 class KUser::Private : public KShared
32 public:
33 PUSER_INFO_11 userInfo;
34 PSID sid;
36 Private() : userInfo(0), sid(0) {}
38 Private(PUSER_INFO_11 userInfo_, PSID sid_ = 0) : userInfo(userInfo_) {}
40 Private(const QString &name, PSID sid_ = 0) : userInfo(0), sid(0)
42 if (NetUserGetInfo(NULL, (LPCWSTR) name.utf16(), 11, (LPBYTE *) &userInfo) != NERR_Success)
43 goto error;
45 if (!sid_) {
46 DWORD size = 0;
47 SID_NAME_USE nameuse;
48 DWORD cchReferencedDomainName = 0;
50 if (!LookupAccountNameW(NULL, (LPCWSTR) name.utf16(), NULL, &size, NULL, &cchReferencedDomainName, &nameuse))
51 goto error;
52 sid = (PSID) new BYTE[size];
53 if (!LookupAccountNameW(NULL, (LPCWSTR) name.utf16(), sid, &size, NULL, &cchReferencedDomainName, &nameuse))
54 goto error;
56 else {
57 if (!IsValidSid(sid_))
58 goto error;
60 DWORD sidlength = GetLengthSid(sid_);
61 sid = (PSID) new BYTE[sidlength];
62 if (!CopySid(sidlength, sid, sid_))
63 goto error;
66 return;
68 error:
69 delete[] sid;
70 sid = 0;
71 if (userInfo) {
72 NetApiBufferFree(userInfo);
73 userInfo = 0;
77 ~Private()
79 if (userInfo)
80 NetApiBufferFree(userInfo);
82 delete[] sid;
86 KUser::KUser(UIDMode mode)
87 : d(0)
89 Q_UNUSED(mode)
91 DWORD bufferLen = UNLEN + 1;
92 ushort buffer[UNLEN + 1];
94 if (GetUserNameW((LPWSTR) buffer, &bufferLen))
95 d = new Private(QString::fromUtf16(buffer));
98 KUser::KUser(K_UID uid)
99 : d(0)
101 DWORD bufferLen = UNLEN + 1;
102 ushort buffer[UNLEN + 1];
103 SID_NAME_USE eUse;
105 if (LookupAccountSidW(NULL, uid, (LPWSTR) buffer, &bufferLen, NULL, NULL, &eUse))
106 d = new Private(QString::fromUtf16(buffer), uid);
109 KUser::KUser(const QString &name)
110 : d(new Private(name))
114 KUser::KUser(const char *name)
115 :d(new Private(QString::fromLocal8Bit(name)))
119 KUser::KUser(const KUser &user)
120 : d(user.d)
124 KUser &KUser::operator=(const KUser &user)
126 d = user.d;
127 return *this;
130 bool KUser::operator==(const KUser &user) const
132 if (!isValid() || !user.isValid())
133 return false;
134 return EqualSid(d->sid, user.d->sid);
137 bool KUser::operator !=(const KUser &user) const
139 return !operator==(user);
142 bool KUser::isValid() const
144 return d->userInfo != 0 && d->sid != 0;
147 bool KUser::isSuperUser() const
149 return d->userInfo && d->userInfo->usri11_priv == USER_PRIV_ADMIN;
152 QString KUser::loginName() const
154 return (d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_name) : QString());
157 QString KUser::fullName() const
159 return (d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_full_name) : QString());
162 QString KUser::homeDir() const
164 return QDir::fromNativeSeparators(qgetenv("USERPROFILE"));
167 QString KUser::faceIconPath() const
169 // FIXME: this needs to be adapted to windows systems (BC changes)
170 return QString();
173 QString KUser::shell() const
175 return QString::fromAscii("cmd.exe");
178 QList<KUserGroup> KUser::groups() const
180 QList<KUserGroup> result;
182 Q_FOREACH (const QString &name, groupNames()) {
183 result.append(KUserGroup(name));
186 return result;
189 QStringList KUser::groupNames() const
191 QStringList result;
193 if (!d->userInfo) {
194 return result;
197 PGROUP_USERS_INFO_0 pGroups = NULL;
198 DWORD dwEntriesRead = 0;
199 DWORD dwTotalEntries = 0;
200 NET_API_STATUS nStatus;
202 nStatus = NetUserGetGroups(NULL, d->userInfo->usri11_name, 0, (LPBYTE *) &pGroups, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries);
204 if (nStatus == NERR_Success) {
205 for (DWORD i = 0; i < dwEntriesRead; ++i) {
206 result.append(QString::fromUtf16((ushort *) pGroups[i].grui0_name));
210 if (pGroups) {
211 NetApiBufferFree(pGroups);
214 return result;
217 K_UID KUser::uid() const
219 return d->sid;
222 QVariant KUser::property(UserProperty which) const
224 if (which == FullName)
225 return QVariant(d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_full_name) : QString());
227 return QVariant();
230 QList<KUser> KUser::allUsers()
232 QList<KUser> result;
234 NET_API_STATUS nStatus;
235 PUSER_INFO_11 pUser = NULL;
236 DWORD dwEntriesRead = 0;
237 DWORD dwTotalEntries = 0;
238 DWORD dwResumeHandle = 0;
240 KUser tmp;
242 do {
243 nStatus = NetUserEnum(NULL, 11, 0, (LPBYTE*) &pUser, 1, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
245 if ((nStatus == NERR_Success || nStatus == ERROR_MORE_DATA) && dwEntriesRead > 0) {
246 tmp.d = new Private(pUser);
247 result.append(tmp);
249 } while (nStatus == ERROR_MORE_DATA);
251 return result;
254 QStringList KUser::allUserNames()
256 QStringList result;
258 NET_API_STATUS nStatus;
259 PUSER_INFO_0 pUsers = NULL;
260 DWORD dwEntriesRead = 0;
261 DWORD dwTotalEntries = 0;
263 nStatus = NetUserEnum(NULL, 0, 0, (LPBYTE*) &pUsers, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL);
265 if (nStatus == NERR_Success) {
266 for (DWORD i = 0; i < dwEntriesRead; ++i) {
267 result.append(QString::fromUtf16((ushort *) pUsers[i].usri0_name));
271 if (pUsers) {
272 NetApiBufferFree(pUsers);
275 return result;
278 KUser::~KUser()
282 class KUserGroup::Private : public KShared
284 public:
285 PGROUP_INFO_0 groupInfo;
287 Private() : groupInfo(NULL) {}
288 Private(PGROUP_INFO_0 groupInfo_) : groupInfo(groupInfo_) {}
289 Private(const QString &Name) : groupInfo(NULL)
291 NetGroupGetInfo(NULL, (PCWSTR) Name.utf16(), 0, (PBYTE *) &groupInfo);
294 ~Private()
296 if (groupInfo) {
297 NetApiBufferFree(groupInfo);
302 KUserGroup::KUserGroup(const QString &_name)
303 : d(new Private(_name))
307 KUserGroup::KUserGroup(const char *_name)
308 : d(new Private(QString(_name)))
312 KUserGroup::KUserGroup(const KUserGroup &group)
313 : d(group.d)
317 KUserGroup& KUserGroup::operator =(const KUserGroup &group)
319 d = group.d;
320 return *this;
323 bool KUserGroup::operator==(const KUserGroup &group) const
325 if (d->groupInfo == NULL || group.d->groupInfo == NULL) {
326 return false;
328 return wcscmp(d->groupInfo->grpi0_name, group.d->groupInfo->grpi0_name) == 0;
331 bool KUserGroup::operator!=(const KUserGroup &group) const
333 return !operator==(group);
336 bool KUserGroup::isValid() const
338 return d->groupInfo != NULL;
341 QString KUserGroup::name() const
343 return QString::fromUtf16((ushort *) d->groupInfo->grpi0_name);
346 QList<KUser> KUserGroup::users() const
348 QList<KUser> Result;
350 Q_FOREACH(const QString &user, userNames()) {
351 Result.append(KUser(user));
354 return Result;
357 QStringList KUserGroup::userNames() const
359 QStringList result;
361 if (!d->groupInfo) {
362 return result;
365 PGROUP_USERS_INFO_0 pUsers = NULL;
366 DWORD dwEntriesRead = 0;
367 DWORD dwTotalEntries = 0;
368 NET_API_STATUS nStatus;
370 nStatus = NetGroupGetUsers(NULL, d->groupInfo->grpi0_name, 0, (LPBYTE *) &pUsers, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL);
372 if (nStatus == NERR_Success) {
373 for (DWORD i = 0; i < dwEntriesRead; ++i) {
374 result.append(QString::fromUtf16((ushort *) pUsers[i].grui0_name));
378 if (pUsers) {
379 NetApiBufferFree(pUsers);
382 return result;
385 QList<KUserGroup> KUserGroup::allGroups()
387 QList<KUserGroup> result;
389 NET_API_STATUS nStatus;
390 PGROUP_INFO_0 pGroup=NULL;
391 DWORD dwEntriesRead=0;
392 DWORD dwTotalEntries=0;
393 DWORD dwResumeHandle=0;
395 KUserGroup tmp("");
397 do {
398 nStatus = NetGroupEnum(NULL, 0, (LPBYTE*) &pGroup, 1, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
400 if ((nStatus == NERR_Success || nStatus == ERROR_MORE_DATA) && dwEntriesRead > 0) {
401 tmp.d = new Private(pGroup);
402 result.append(tmp);
404 } while (nStatus == ERROR_MORE_DATA);
406 return result;
409 QStringList KUserGroup::allGroupNames()
411 QStringList result;
413 NET_API_STATUS nStatus;
414 PGROUP_INFO_0 pGroups=NULL;
415 DWORD dwEntriesRead=0;
416 DWORD dwTotalEntries=0;
418 nStatus = NetGroupEnum(NULL, 0, (LPBYTE*) &pGroups, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL);
420 if (nStatus == NERR_Success) {
421 for (DWORD i = 0; i < dwEntriesRead; ++i) {
422 result.append(QString::fromUtf16((ushort *) pGroups[i].grpi0_name));
426 if (pGroups) {
427 NetApiBufferFree(pGroups);
430 return result;
433 KUserGroup::~KUserGroup()