• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDECore

kuser_win.cpp

Go to the documentation of this file.
00001 /*
00002  *  KUser - represent a user/account (Windows)
00003  *  Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
00004  *
00005  *  This library is free software; you can redistribute it and/or
00006  *  modify it under the terms of the GNU Library General Public
00007  *  License as published by the Free Software Foundation; either
00008  *  version 2 of the License, or (at your option) any later version.
00009  *
00010  *  This library is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Library General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Library General Public License
00016  *  along with this library; see the file COPYING.LIB.  If not, write to
00017  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  *  Boston, MA 02110-1301, USA.
00019  */
00020 
00021 #include "kuser.h"
00022 
00023 #include <QtCore/QMutableStringListIterator>
00024 #include <QtCore/QDebug>
00025 #include <QtCore/QDir>
00026 
00027 #include <windows.h>
00028 #include <lm.h>
00029 #include <Sddl.h>
00030 #include <userenv.h>
00031 
00032 class KUser::Private : public KShared
00033 {
00034     public:
00035         PUSER_INFO_11 userInfo;
00036         PSID sid;
00037 
00038         Private() : userInfo(0), sid(0) {}
00039 
00040         Private(PUSER_INFO_11 userInfo_, PSID sid_ = 0) : userInfo(userInfo_) {}
00041 
00042         Private(const QString &name, PSID sid_ = 0) : userInfo(0), sid(NULL)
00043         {
00044             if (NetUserGetInfo(NULL, (LPCWSTR) name.utf16(), 11, (LPBYTE *) &userInfo) != NERR_Success)
00045                 goto error;
00046 
00047             if (!sid_) {
00048                 DWORD size = 0;
00049                 SID_NAME_USE nameuse;
00050                 DWORD cchReferencedDomainName = 0;
00051                 WCHAR* referencedDomainName = NULL;
00052                 
00053                 // the following line definitely fails:
00054                 // both the sizes for sid and for referencedDomainName are Null
00055                 // the needed sizes are set in size and cchReferencedDomainName
00056                 LookupAccountNameW(NULL, (LPCWSTR) name.utf16(), sid, &size, referencedDomainName, &cchReferencedDomainName, &nameuse);
00057                 sid = (PSID) new SID[size + 1];
00058                 referencedDomainName = new WCHAR[cchReferencedDomainName + 1];
00059                 if (!LookupAccountNameW(NULL, (LPCWSTR) name.utf16(), sid, &size, referencedDomainName, &cchReferencedDomainName, &nameuse)) {
00060                     delete[] referencedDomainName;
00061                     goto error;
00062                 }
00063 
00064                 // if you want to see both the DomainName and the sid of the user
00065                 // uncomment the following lines
00066 /*                LPWSTR sidstring;
00067                 ConvertSidToStringSidW(sid, &sidstring);
00068                 qDebug() << QString("\\\\") + QString::fromUtf16(reinterpret_cast<ushort*>(referencedDomainName)) + \
00069                             "\\" + name + "(" + QString::fromUtf16(reinterpret_cast<ushort*>(sidstring)) + ")";
00070 
00071                 LocalFree(sidstring);*/
00072                 delete[] referencedDomainName;
00073             }
00074             else {
00075                 if (!IsValidSid(sid_))
00076                     goto error;
00077 
00078                 DWORD sidlength = GetLengthSid(sid_);
00079                 sid = (PSID) new BYTE[sidlength];
00080                 if (!CopySid(sidlength, sid, sid_))
00081                     goto error;
00082             }
00083 
00084             return;
00085 
00086           error:
00087             delete[] sid;
00088             sid = 0;
00089             if (userInfo) {
00090                 NetApiBufferFree(userInfo);
00091                 userInfo = 0;
00092             }
00093         }
00094 
00095         ~Private()
00096         {
00097             if (userInfo)
00098                 NetApiBufferFree(userInfo);
00099 
00100             delete[] sid;
00101         }
00102 };
00103 
00104 KUser::KUser(UIDMode mode)
00105         : d(0)
00106 {
00107     Q_UNUSED(mode)
00108 
00109     DWORD bufferLen = UNLEN + 1;
00110     ushort buffer[UNLEN + 1];
00111 
00112     if (GetUserNameW((LPWSTR) buffer, &bufferLen))
00113         d = new Private(QString::fromUtf16(buffer));
00114 }
00115 
00116 KUser::KUser(K_UID uid)
00117     : d(0)
00118 {
00119     DWORD bufferLen = UNLEN + 1;
00120     ushort buffer[UNLEN + 1];
00121     SID_NAME_USE eUse;
00122 
00123     if (LookupAccountSidW(NULL, uid, (LPWSTR) buffer, &bufferLen, NULL, NULL, &eUse))
00124         d = new Private(QString::fromUtf16(buffer), uid);
00125 }
00126 
00127 KUser::KUser(const QString &name)
00128     : d(new Private(name))
00129 {
00130 }
00131 
00132 KUser::KUser(const char *name)
00133     :d(new Private(QString::fromLocal8Bit(name)))
00134 {
00135 }
00136 
00137 KUser::KUser(const KUser &user)
00138     : d(user.d)
00139 {
00140 }
00141 
00142 KUser &KUser::operator=(const KUser &user)
00143 {
00144     d = user.d;
00145     return *this;
00146 }
00147 
00148 bool KUser::operator==(const KUser &user) const
00149 {
00150     if (!isValid() || !user.isValid())
00151         return false;
00152     return EqualSid(d->sid, user.d->sid);
00153 }
00154 
00155 bool KUser::operator !=(const KUser &user) const
00156 {
00157     return !operator==(user);
00158 }
00159 
00160 bool KUser::isValid() const
00161 {
00162     return d->userInfo != 0 && d->sid != 0;
00163 }
00164 
00165 bool KUser::isSuperUser() const
00166 {
00167     return d->userInfo && d->userInfo->usri11_priv == USER_PRIV_ADMIN;
00168 }
00169 
00170 QString KUser::loginName() const
00171 {
00172     return (d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_name) : QString());
00173 }
00174 
00175 QString KUser::fullName() const
00176 {
00177     return (d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_full_name) : QString());
00178 }
00179 
00180 QString KUser::homeDir() const
00181 {
00182     return QDir::fromNativeSeparators(qgetenv("USERPROFILE"));
00183 }
00184 
00185 QString KUser::faceIconPath() const
00186 {
00187     // FIXME: this needs to be adapted to windows systems (BC changes)
00188     return QString();
00189 }
00190 
00191 QString KUser::shell() const
00192 {
00193     return QString::fromAscii("cmd.exe");
00194 }
00195 
00196 QList<KUserGroup> KUser::groups() const
00197 {
00198     QList<KUserGroup> result;
00199 
00200     Q_FOREACH (const QString &name, groupNames()) {
00201         result.append(KUserGroup(name));
00202     }
00203 
00204     return result;
00205 }
00206 
00207 QStringList KUser::groupNames() const
00208 {
00209     QStringList result;
00210 
00211     if (!d->userInfo) {
00212         return result;
00213     }
00214 
00215     PGROUP_USERS_INFO_0 pGroups = NULL;
00216     DWORD dwEntriesRead = 0;
00217     DWORD dwTotalEntries = 0;
00218     NET_API_STATUS nStatus;
00219 
00220     nStatus = NetUserGetGroups(NULL, d->userInfo->usri11_name, 0, (LPBYTE *) &pGroups, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries);
00221 
00222     if (nStatus == NERR_Success) {
00223         for (DWORD i = 0; i < dwEntriesRead; ++i) {
00224             result.append(QString::fromUtf16((ushort *) pGroups[i].grui0_name));
00225         }
00226     }
00227 
00228     if (pGroups) {
00229         NetApiBufferFree(pGroups);
00230     }
00231 
00232     return result;
00233 }
00234 
00235 K_UID KUser::uid() const
00236 {
00237     return d->sid;
00238 }
00239 
00240 QVariant KUser::property(UserProperty which) const
00241 {
00242     if (which == FullName) 
00243         return QVariant(d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_full_name) : QString());
00244 
00245     return QVariant();
00246 }
00247 
00248 QList<KUser> KUser::allUsers()
00249 {
00250     QList<KUser> result;
00251 
00252     NET_API_STATUS nStatus;
00253     PUSER_INFO_11 pUser = NULL;
00254     DWORD dwEntriesRead = 0;
00255     DWORD dwTotalEntries = 0;
00256     DWORD dwResumeHandle = 0;
00257 
00258     KUser tmp;
00259 
00260     do {
00261         nStatus = NetUserEnum(NULL, 11, 0, (LPBYTE*) &pUser, 1, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
00262 
00263         if ((nStatus == NERR_Success || nStatus == ERROR_MORE_DATA) && dwEntriesRead > 0) {
00264             tmp.d = new Private(pUser);
00265             result.append(tmp);
00266         }
00267     } while (nStatus == ERROR_MORE_DATA);
00268 
00269     return result;
00270 }
00271 
00272 QStringList KUser::allUserNames()
00273 {
00274     QStringList result;
00275 
00276     NET_API_STATUS nStatus;
00277     PUSER_INFO_0 pUsers = NULL;
00278     DWORD dwEntriesRead = 0;
00279     DWORD dwTotalEntries = 0;
00280 
00281     nStatus = NetUserEnum(NULL, 0, 0, (LPBYTE*) &pUsers, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL);
00282 
00283     if (nStatus == NERR_Success) {
00284         for (DWORD i = 0; i < dwEntriesRead; ++i) {
00285             result.append(QString::fromUtf16((ushort *) pUsers[i].usri0_name));
00286         }
00287     }
00288 
00289     if (pUsers) {
00290         NetApiBufferFree(pUsers);
00291     }
00292 
00293     return result;
00294 }
00295 
00296 KUser::~KUser()
00297 {
00298 }
00299 
00300 class KUserGroup::Private : public KShared
00301 {
00302     public:
00303         PGROUP_INFO_0 groupInfo;
00304 
00305         Private() : groupInfo(NULL) {}
00306         Private(PGROUP_INFO_0 groupInfo_) : groupInfo(groupInfo_) {}
00307         Private(const QString &Name) : groupInfo(NULL)
00308         {
00309             NetGroupGetInfo(NULL, (PCWSTR) Name.utf16(), 0, (PBYTE *) &groupInfo);
00310         }
00311 
00312         ~Private()
00313         {
00314             if (groupInfo) {
00315                 NetApiBufferFree(groupInfo);
00316             }
00317         }
00318 };
00319 
00320 KUserGroup::KUserGroup(const QString &_name)
00321     : d(new Private(_name))
00322 {
00323 }
00324 
00325 KUserGroup::KUserGroup(const char *_name)
00326     : d(new Private(QString(_name)))
00327 {
00328 }
00329 
00330 KUserGroup::KUserGroup(const KUserGroup &group)
00331     : d(group.d)
00332 {
00333 }
00334 
00335 KUserGroup& KUserGroup::operator =(const KUserGroup &group)
00336 {
00337     d = group.d;
00338     return *this;
00339 }
00340 
00341 bool KUserGroup::operator==(const KUserGroup &group) const
00342 {
00343     if (d->groupInfo == NULL || group.d->groupInfo == NULL) {
00344         return false;
00345     }
00346     return wcscmp(d->groupInfo->grpi0_name, group.d->groupInfo->grpi0_name) == 0;
00347 }
00348 
00349 bool KUserGroup::operator!=(const KUserGroup &group) const
00350 {
00351     return !operator==(group);
00352 }
00353 
00354 bool KUserGroup::isValid() const
00355 {
00356     return d->groupInfo != NULL;
00357 }
00358 
00359 QString KUserGroup::name() const
00360 {
00361     return QString::fromUtf16((ushort *) d->groupInfo->grpi0_name);
00362 }
00363 
00364 QList<KUser> KUserGroup::users() const
00365 {
00366     QList<KUser> Result;
00367 
00368     Q_FOREACH(const QString &user, userNames()) {
00369         Result.append(KUser(user));
00370     }
00371 
00372     return Result;
00373 }
00374 
00375 QStringList KUserGroup::userNames() const
00376 {
00377     QStringList result;
00378 
00379     if (!d->groupInfo) {
00380         return result;
00381     }
00382 
00383     PGROUP_USERS_INFO_0 pUsers = NULL;
00384     DWORD dwEntriesRead = 0;
00385     DWORD dwTotalEntries = 0;
00386     NET_API_STATUS nStatus;
00387 
00388     nStatus = NetGroupGetUsers(NULL, d->groupInfo->grpi0_name, 0, (LPBYTE *) &pUsers, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL);
00389 
00390     if (nStatus == NERR_Success) {
00391         for (DWORD i = 0; i < dwEntriesRead; ++i) {
00392             result.append(QString::fromUtf16((ushort *) pUsers[i].grui0_name));
00393         }
00394     }
00395 
00396     if (pUsers) {
00397         NetApiBufferFree(pUsers);
00398     }
00399 
00400     return result;
00401 }
00402 
00403 QList<KUserGroup> KUserGroup::allGroups()
00404 {
00405     QList<KUserGroup> result;
00406 
00407     NET_API_STATUS nStatus;
00408     PGROUP_INFO_0 pGroup=NULL;
00409     DWORD dwEntriesRead=0;
00410     DWORD dwTotalEntries=0;
00411     DWORD dwResumeHandle=0;
00412 
00413     KUserGroup tmp("");
00414 
00415     do {
00416         nStatus = NetGroupEnum(NULL, 0, (LPBYTE*) &pGroup, 1, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
00417 
00418         if ((nStatus == NERR_Success || nStatus == ERROR_MORE_DATA) && dwEntriesRead > 0) {
00419             tmp.d = new Private(pGroup);
00420             result.append(tmp);
00421         }
00422     } while (nStatus == ERROR_MORE_DATA);
00423 
00424     return result;
00425 }
00426 
00427 QStringList KUserGroup::allGroupNames()
00428 {
00429     QStringList result;
00430 
00431     NET_API_STATUS nStatus;
00432     PGROUP_INFO_0 pGroups=NULL;
00433     DWORD dwEntriesRead=0;
00434     DWORD dwTotalEntries=0;
00435 
00436     nStatus = NetGroupEnum(NULL, 0, (LPBYTE*) &pGroups, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL);
00437 
00438     if (nStatus == NERR_Success) {
00439         for (DWORD i = 0; i < dwEntriesRead; ++i) {
00440             result.append(QString::fromUtf16((ushort *) pGroups[i].grpi0_name));
00441         }
00442     }
00443 
00444     if (pGroups) {
00445         NetApiBufferFree(pGroups);
00446     }
00447 
00448     return result;
00449 }
00450 
00451 KUserGroup::~KUserGroup()
00452 {
00453 }

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal