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