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.
23 #include <QtCore/QMutableStringListIterator>
24 #include <QtCore/QDir>
30 class KUser::Private
: public KShared
33 PUSER_INFO_11 userInfo
;
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
)
48 DWORD cchReferencedDomainName
= 0;
50 if (!LookupAccountNameW(NULL
, (LPCWSTR
) name
.utf16(), NULL
, &size
, NULL
, &cchReferencedDomainName
, &nameuse
))
52 sid
= (PSID
) new BYTE
[size
];
53 if (!LookupAccountNameW(NULL
, (LPCWSTR
) name
.utf16(), sid
, &size
, NULL
, &cchReferencedDomainName
, &nameuse
))
57 if (!IsValidSid(sid_
))
60 DWORD sidlength
= GetLengthSid(sid_
);
61 sid
= (PSID
) new BYTE
[sidlength
];
62 if (!CopySid(sidlength
, sid
, sid_
))
72 NetApiBufferFree(userInfo
);
80 NetApiBufferFree(userInfo
);
86 KUser::KUser(UIDMode 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
)
101 DWORD bufferLen
= UNLEN
+ 1;
102 ushort buffer
[UNLEN
+ 1];
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
)
124 KUser
&KUser::operator=(const KUser
&user
)
130 bool KUser::operator==(const KUser
&user
) const
132 if (!isValid() || !user
.isValid())
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)
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
));
189 QStringList
KUser::groupNames() const
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
));
211 NetApiBufferFree(pGroups
);
217 K_UID
KUser::uid() const
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());
230 QList
<KUser
> KUser::allUsers()
234 NET_API_STATUS nStatus
;
235 PUSER_INFO_11 pUser
= NULL
;
236 DWORD dwEntriesRead
= 0;
237 DWORD dwTotalEntries
= 0;
238 DWORD dwResumeHandle
= 0;
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
);
249 } while (nStatus
== ERROR_MORE_DATA
);
254 QStringList
KUser::allUserNames()
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
));
272 NetApiBufferFree(pUsers
);
282 class KUserGroup::Private
: public KShared
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
);
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
)
317 KUserGroup
& KUserGroup::operator =(const KUserGroup
&group
)
323 bool KUserGroup::operator==(const KUserGroup
&group
) const
325 if (d
->groupInfo
== NULL
|| group
.d
->groupInfo
== NULL
) {
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
350 Q_FOREACH(const QString
&user
, userNames()) {
351 Result
.append(KUser(user
));
357 QStringList
KUserGroup::userNames() const
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
));
379 NetApiBufferFree(pUsers
);
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;
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
);
404 } while (nStatus
== ERROR_MORE_DATA
);
409 QStringList
KUserGroup::allGroupNames()
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
));
427 NetApiBufferFree(pGroups
);
433 KUserGroup::~KUserGroup()