[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    KUser windows port and small API changes
From:       "Nhuh Put" <nhuh.put () web ! de>
Date:       2007-09-22 23:40:59
Message-ID: 001901c7fd72$1b29ece0$8a96b053 () spika
[Download RAW message or body]

Hello
I would like to commit this patch on next Monday.
It's a Windows Port of KUser.
As things like room number and phone number are not available on windows, I
removed those methods and added a generic extendedProperty(const QByteArray)
This is only used in one place in kdebase, I would port the user.
I would also rename kuser.cpp to kuser_unix.cpp

	PutHuhn

["kuser.patch" (text/x-patch)]

Index: kuser.cpp
===================================================================
--- kuser.cpp	(revision 715697)
+++ kuser.cpp	(working copy)
@@ -34,8 +34,8 @@
     uid_t uid;
     gid_t gid;
     QString loginName, fullName;
-    QString roomNumber, workPhone, homePhone;
     QString homeDir, shell;
+    QMap<const QByteArray, QVariant> extendedProperties;
 
     Private() : uid(uid_t(-1)), gid(gid_t(-1)) {}
     Private(const char *name) : uid(uid_t(-1)), gid(gid_t(-1))
@@ -60,9 +60,9 @@
             gid = p->pw_gid;
             loginName = QString::fromLocal8Bit(p->pw_name);
             fullName = gecosList[0];
-            roomNumber = gecosList[1];
-            workPhone = gecosList[2];
-            homePhone = gecosList[3];
+            extendedProperties["roomnumber"] = QVariant(gecosList[1]);
+            extendedProperties["workphone"] = QVariant(gecosList[2]);
+            extendedProperties["homephone"] = QVariant(gecosList[3]);
             homeDir = QString::fromLocal8Bit(p->pw_dir);
             shell = QString::fromLocal8Bit(p->pw_shell);
         }
@@ -85,7 +85,7 @@
 	}
 }
 
-KUser::KUser(uid_t _uid)
+KUser::KUser(K_UID _uid)
     : d(new Private( ::getpwuid( _uid ) ))
 {
 }
@@ -128,11 +128,11 @@
 	return uid() != uid_t(-1);
 }
 
-uid_t KUser::uid() const {
+const K_UID KUser::uid() const {
 	return d->uid;
 }
 
-gid_t KUser::gid() const {
+const K_GID KUser::gid() const {
 	return d->gid;
 }
 
@@ -148,18 +148,6 @@
 	return d->fullName;
 }
 
-QString KUser::roomNumber() const {
-	return d->roomNumber;
-}
-
-QString KUser::workPhone() const {
-	return d->workPhone;
-}
-
-QString KUser::homePhone() const {
-	return d->homePhone;
-}
-
 QString KUser::homeDir() const {
 	return d->homeDir;
 }
@@ -194,6 +182,10 @@
   return result;
 }
 
+QVariant KUser::extendedProperty(const QByteArray &which) const
+{
+    return d->extendedProperties.value(which);
+}
 
 QList<KUser> KUser::allUsers() {
   QList<KUser> result;
@@ -257,7 +249,7 @@
     d = new Private(getgrgid(KUser(mode).gid()));
 }
 
-KUserGroup::KUserGroup(gid_t _gid)
+KUserGroup::KUserGroup(K_GID _gid)
     : d(new Private(getgrgid(_gid)))
 {
 }
@@ -299,7 +291,7 @@
 	return gid() != gid_t(-1);
 }
 
-gid_t KUserGroup::gid() const {
+K_GID KUserGroup::gid() const {
 	return d->gid;
 }
 
Index: kuser.h
===================================================================
--- kuser.h	(revision 715697)
+++ kuser.h	(working copy)
@@ -23,15 +23,27 @@
 #define KUSER_H
 
 #include <kdecore_export.h>
-#include "ksharedptr.h"
-#include <sys/types.h>
+#include <ksharedptr.h>
 
+#include <QtCore/QVariant>
+
 class KUserGroup;
 class QString;
 class QStringList;
-struct passwd;
 template <class T> class QList;
 
+#ifdef Q_OS_WIN
+typedef void *K_UID;
+typedef void *K_GID;
+#else
+#include <sys/types.h>
+typedef uid_t K_UID;
+typedef gid_t K_GID;
+struct passwd;
+struct group;
+#endif
+
+
 /**
  * @short Represents a user on your system
  *
@@ -71,7 +83,7 @@
    * If the user does not exist isValid() will return false.
    * @param uid the user id
    */
-  explicit KUser(uid_t uid);
+  explicit KUser(K_UID uid);
 
   /**
    * Creates an object that contains information about the user with the given
@@ -89,6 +101,7 @@
    */
   explicit KUser(const char* name);
 
+#ifndef Q_OS_WIN
   /**
    * Creates an object from a passwd structure.
    * If the pointer is null isValid() will return false.
@@ -96,6 +109,7 @@
    * @param p the passwd structure to create the user from
    */
   explicit KUser(const passwd *p);
+#endif
 
   /**
    * Creates an object from another KUser object
@@ -133,13 +147,15 @@
    * Returns the user id of the user.
    * @return the id of the user or -1 if user is invalid
    */
-  uid_t uid() const;
+  const K_UID uid() const;
 
+#ifndef Q_OS_WIN
   /**
    * Returns the group id of the user.
    * @return the id of the group or -1 if user is invalid
    */
-  gid_t gid() const;
+  const K_GID gid() const;
+#endif
 
   /**
    * Checks whether the user is the super user (root).
@@ -160,27 +176,6 @@
   QString fullName() const;
 
   /**
-   * The user's room number.
-   * @return the room number of the user or QString() if not set or the
-   *         user is invalid
-   */
-  QString roomNumber() const;
-
-  /**
-   * The user's work phone.
-   * @return the work phone of the user or QString() if not set or the
-   *         user is invalid
-   */
-  QString workPhone() const;
-
-  /**
-   * The user's home phone.
-   * @return the home phone of the user or QString() if not set or the
-   *         user is invalid
-   */
-  QString homePhone() const;
-
-  /**
    * The path to the user's home directory.
    * @return the home directory of the user or QString() if the
    *         user is invalid
@@ -206,6 +201,15 @@
    */
   QStringList groupNames() const;
 
+  /**
+   * Retruns an extended property or an invalid
+   * QVariant if the property is not set.
+   *
+   * currently supported properties: roomnumer, workphone and homephone
+   *
+   * \return a QVariant with value of the property
+   */
+  QVariant extendedProperty(const QByteArray &which) const ;
 
   /**
    * Destructor.
@@ -229,8 +233,6 @@
   KSharedPtr<Private> d;
 };
 
-struct group;
-
 /**
  * @short Represents a group on your system
  *
@@ -246,6 +248,21 @@
 public:
 
   /**
+   * Create an object from a group name.
+   * If the group does not exist, isValid() will return false.
+   * @param name the name of the group
+   */
+  explicit KUserGroup(const QString& name);
+
+  /**
+   * Create an object from a group name.
+   * If the group does not exist, isValid() will return false.
+   * @param name the name of the group
+   */
+  explicit KUserGroup(const char *name);
+
+#ifndef Q_OS_WIN
+  /**
    * Create an object from the group of the current user.
    * @param mode if #KUser::UseEffectiveUID is passed the effective user
    *        will be used. If #KUser::UseRealUserID is passed the real user
@@ -262,28 +279,15 @@
    * If the group does not exist, isValid() will return false.
    * @param gid the group id
    */
-  explicit KUserGroup(gid_t gid);
+  explicit KUserGroup(K_GID gid);
 
   /**
-   * Create an object from a group name.
-   * If the group does not exist, isValid() will return false.
-   * @param name the name of the group
-   */
-  explicit KUserGroup(const QString& name);
-
-  /**
-   * Create an object from a group name.
-   * If the group does not exist, isValid() will return false.
-   * @param name the name of the group
-   */
-  explicit KUserGroup(const char *name);
-
-  /**
    * Creates an object from a group structure.
    * If the pointer is null, isValid() will return false.
    * @param g the group structure to create the group from.
    */
   explicit KUserGroup(const group *g);
+#endif
 
   /**
    * Creates a new KUserGroup instance from another KUserGroup object
@@ -320,11 +324,13 @@
    */
   bool isValid() const;
 
+#ifndef Q_OS_WIN
   /**
    * Returns the group id of the group.
    * @return the group id of the group or -1 if the group is invalid
    */
-  gid_t gid() const;
+  K_GID gid() const;
+#endif
 
   /**
    * The name of the group.
Index: kuser_win.cpp
===================================================================
--- kuser_win.cpp	(revision 0)
+++ kuser_win.cpp	(revision 0)
@@ -0,0 +1,438 @@
+/*
+ *  KUser - represent a user/account (Windows)
+ *  Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ */
+
+#include "kuser.h"
+
+#include <QtCore/QMutableStringListIterator>
+#include <QtCore/QDir>
+
+#include <windows.h>
+#include <lm.h>
+#include <Userenv.h>
+
+class KUser::Private : public KShared
+{
+    public:
+        PUSER_INFO_11 userInfo;
+        PSID sid;
+
+        Private() : userInfo(0), sid(0) {}
+
+        Private(PUSER_INFO_11 userInfo_, PSID sid_ = 0) : userInfo(userInfo_) {}
+
+        Private(const QString &name, PSID sid_ = 0) : userInfo(0), sid(0)
+        {
+            if (NetUserGetInfo(NULL, (LPCWSTR) name.utf16(), 11, (LPBYTE *) \
&userInfo) != NERR_Success) +                goto error;
+
+            if (!sid_) {
+                DWORD size = 0;
+                SID_NAME_USE nameuse;
+                DWORD cchReferencedDomainName = 0;
+
+                if (!LookupAccountNameW(NULL, (LPCWSTR) name.utf16(), NULL, &size, \
NULL, &cchReferencedDomainName, &nameuse)) +                    goto error;
+                sid = (PSID) new BYTE[size];
+                if (!LookupAccountNameW(NULL, (LPCWSTR) name.utf16(), sid, &size, \
NULL, &cchReferencedDomainName, &nameuse)) +                    goto error;
+            }
+            else {
+                if (!IsValidSid(sid_))
+                    goto error;
+
+                DWORD sidlength = GetLengthSid(sid_);
+                sid = (PSID) new BYTE[sidlength];
+                if (!CopySid(sidlength, sid, sid_))
+                    goto error;
+            }
+
+            return;
+
+          error:
+            delete[] sid;
+            sid = 0;
+            if (userInfo) {
+                NetApiBufferFree(userInfo);
+                userInfo = 0;
+            }
+        }
+
+        ~Private()
+        {
+            if (userInfo)
+                NetApiBufferFree(userInfo);
+            
+            delete[] sid;
+        }
+};
+
+KUser::KUser(UIDMode mode) 
+        : d(0)
+{
+    Q_UNUSED(mode)
+
+    DWORD bufferLen = UNLEN + 1;
+    ushort buffer[UNLEN + 1];
+
+    if (GetUserNameW((LPWSTR) buffer, &bufferLen))
+        d = new Private(QString::fromUtf16(buffer));
+}
+
+KUser::KUser(K_UID uid)
+    : d(0)
+{
+    DWORD bufferLen = UNLEN + 1;
+    ushort buffer[UNLEN + 1];
+    SID_NAME_USE eUse;
+
+    if (LookupAccountSidW(NULL, uid, (LPWSTR) buffer, &bufferLen, NULL, NULL, \
&eUse)) +        d = new Private(QString::fromUtf16(buffer), uid);
+}
+
+KUser::KUser(const QString &name)
+    : d(new Private(name))
+{
+}
+
+KUser::KUser(const char *name)
+    :d(new Private(QString::fromLocal8Bit(name)))
+{
+}
+
+KUser::KUser(const KUser &user)
+    : d(user.d)
+{
+}
+
+KUser &KUser::operator=(const KUser &user)
+{
+    d = user.d;
+    return *this;
+}
+
+bool KUser::operator==(const KUser &user) const
+{
+    if (!isValid() || !user.isValid())
+        return false;
+    return EqualSid(d->sid, user.d->sid);
+}
+
+bool KUser::operator !=(const KUser &user) const
+{
+    return !operator==(user);
+}
+
+bool KUser::isValid() const
+{
+    return d->userInfo != 0 && d->sid != 0;
+}
+
+bool KUser::isSuperUser() const
+{
+    return d->userInfo && d->userInfo->usri11_priv == USER_PRIV_ADMIN;
+}
+
+QString KUser::loginName() const
+{
+    return (d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_name) : \
QString()); +}
+
+QString KUser::fullName() const
+{
+    return (d->userInfo ? QString::fromUtf16((ushort *) \
d->userInfo->usri11_full_name) : QString()); +}
+
+QString KUser::homeDir() const
+{
+    wchar_t profilesDir[MAX_PATH + 1] = { 0 };
+    DWORD Size = MAX_PATH+1;
+ 
+    if (d->userInfo == NULL || !GetProfilesDirectoryW(profilesDir, &Size)) {
+        return QString();
+    }
+
+    QDir dir = QDir::fromNativeSeparators(QString::fromUtf16((ushort *) \
profilesDir)); +    return \
dir.absolutePath().append(QLatin1Char('/')).append(loginName()); +}
+
+QString KUser::shell() const
+{
+    return QString::fromAscii("cmd.exe");
+}
+
+QList<KUserGroup> KUser::groups() const
+{
+    QList<KUserGroup> result;
+
+    QStringList names(groupNames());
+
+    for (QStringList::const_iterator it = names.begin(); it != names.end(); ++it) {
+        result.append(KUserGroup(*it));
+    }
+
+    return result;
+}
+
+QStringList KUser::groupNames() const
+{
+    QStringList result;
+ 
+    if (!d->userInfo) {
+        return result;
+    }
+
+    PGROUP_USERS_INFO_0 pGroups = NULL;
+    DWORD dwEntriesRead = 0;
+    DWORD dwTotalEntries = 0;
+    NET_API_STATUS nStatus;
+
+    nStatus = NetUserGetGroups(NULL, d->userInfo->usri11_name, 0, (LPBYTE *) \
&pGroups, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries); +
+    if (nStatus == NERR_Success) {
+        for (DWORD i = 0; i < dwEntriesRead; ++i) {
+            result.append(QString::fromUtf16((ushort *) pGroups[i].grui0_name));
+        }
+    }
+
+    if (pGroups) {
+        NetApiBufferFree(pGroups);
+    }
+
+    return result;
+}
+
+const K_UID KUser::uid() const
+{
+    return d->sid;
+}
+
+QVariant KUser::extendedProperty(const QByteArray &which) const
+{
+    return QVariant();
+}
+
+QList<KUser> KUser::allUsers()
+{
+    QList<KUser> result;
+
+    NET_API_STATUS nStatus;
+    PUSER_INFO_11 pUser = NULL;
+    DWORD dwEntriesRead = 0;
+    DWORD dwTotalEntries = 0;
+    DWORD dwResumeHandle = 0;
+
+    KUser tmp;
+
+    do {
+        nStatus = NetUserEnum(NULL, 11, 0, (LPBYTE*) &pUser, 1, &dwEntriesRead, \
&dwTotalEntries, &dwResumeHandle); +
+        if ((nStatus == NERR_Success || nStatus == ERROR_MORE_DATA) && dwEntriesRead \
> 0) { +            tmp.d = new Private(pUser);
+            result.append(tmp);
+        }
+    } while (nStatus == ERROR_MORE_DATA);
+
+    return result;
+}
+
+QStringList KUser::allUserNames()
+{
+    QStringList result;
+
+    NET_API_STATUS nStatus;
+    PUSER_INFO_0 pUsers = NULL;
+    DWORD dwEntriesRead = 0;
+    DWORD dwTotalEntries = 0;
+
+    nStatus = NetUserEnum(NULL, 0, 0, (LPBYTE*) &pUsers, MAX_PREFERRED_LENGTH, \
&dwEntriesRead, &dwTotalEntries, NULL); +
+    if (nStatus == NERR_Success) {
+        for (DWORD i = 0; i < dwEntriesRead; ++i) {
+            result.append(QString::fromUtf16((ushort *) pUsers[i].usri0_name));
+        }
+    }
+
+    if (pUsers) {
+        NetApiBufferFree(pUsers);
+    }
+
+    return result;
+}
+
+KUser::~KUser()
+{
+}
+
+class KUserGroup::Private : public KShared
+{
+    public:
+        PGROUP_INFO_0 groupInfo;
+
+        Private() : groupInfo(NULL) {}
+        Private(PGROUP_INFO_0 groupInfo_) : groupInfo(groupInfo_) {}
+        Private(const QString &Name) : groupInfo(NULL) 
+        {
+            NetGroupGetInfo(NULL, (PCWSTR) Name.utf16(), 0, (PBYTE *) &groupInfo);
+        }
+
+        ~Private()
+        {
+            if (groupInfo) {
+                NetApiBufferFree(groupInfo);
+            }
+        }
+};
+
+KUserGroup::KUserGroup(const QString &_name)
+    : d(new Private(_name))
+{
+}
+
+KUserGroup::KUserGroup(const char *_name)
+    : d(new Private(QString(_name)))
+{
+}
+
+KUserGroup::KUserGroup(const KUserGroup &group)
+    : d(group.d)
+{
+}
+
+KUserGroup& KUserGroup::operator =(const KUserGroup &group)
+{
+    d = group.d;
+    return *this;
+}
+
+bool KUserGroup::operator==(const KUserGroup &group) const
+{
+    if (d->groupInfo == NULL || group.d->groupInfo == NULL) {
+        return false; 
+    }
+    return wcscmp(d->groupInfo->grpi0_name, group.d->groupInfo->grpi0_name) == 0;
+}
+
+bool KUserGroup::operator!=(const KUserGroup &group) const
+{
+    return !operator==(group);
+}
+
+bool KUserGroup::isValid() const
+{
+    return d->groupInfo != NULL;
+}
+
+QString KUserGroup::name() const
+{
+    return QString::fromUtf16((ushort *) d->groupInfo->grpi0_name);
+}
+
+QList<KUser> KUserGroup::users() const
+{
+    QList<KUser> Result;
+
+    QStringList Names(userNames());
+
+    for (QStringList::const_iterator it = Names.begin(); it != Names.end(); ++it) {
+        Result.append(KUser(*it));
+    }
+
+    return Result;
+}
+
+QStringList KUserGroup::userNames() const
+{
+    QStringList result;
+ 
+    if (!d->groupInfo) {
+        return result;
+    }
+
+    PGROUP_USERS_INFO_0 pUsers = NULL;
+    DWORD dwEntriesRead = 0;
+    DWORD dwTotalEntries = 0;
+    NET_API_STATUS nStatus;
+
+    nStatus = NetGroupGetUsers(NULL, d->groupInfo->grpi0_name, 0, (LPBYTE *) \
&pUsers, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL); +
+    if (nStatus == NERR_Success) {
+        for (DWORD i = 0; i < dwEntriesRead; ++i) {
+            result.append(QString::fromUtf16((ushort *) pUsers[i].grui0_name));
+        }
+    }
+
+    if (pUsers) {
+        NetApiBufferFree(pUsers);
+    }
+
+    return result;
+}
+
+QList<KUserGroup> KUserGroup::allGroups()
+{
+    QList<KUserGroup> result;
+
+    NET_API_STATUS nStatus;
+    PGROUP_INFO_0 pGroup=NULL;
+    DWORD dwEntriesRead=0;
+    DWORD dwTotalEntries=0;
+    DWORD dwResumeHandle=0;
+
+    KUserGroup tmp("");
+
+    do {
+        nStatus = NetGroupEnum(NULL, 0, (LPBYTE*) &pGroup, 1, &dwEntriesRead, \
&dwTotalEntries, &dwResumeHandle); +
+        if ((nStatus == NERR_Success || nStatus == ERROR_MORE_DATA) && dwEntriesRead \
> 0) { +            tmp.d = new Private(pGroup);
+            result.append(tmp);
+        }
+    } while (nStatus == ERROR_MORE_DATA);
+
+    return result;
+}
+
+QStringList KUserGroup::allGroupNames()
+{
+    QStringList result;
+
+    NET_API_STATUS nStatus;
+    PGROUP_INFO_0 pGroups=NULL;
+    DWORD dwEntriesRead=0;
+    DWORD dwTotalEntries=0;
+
+    nStatus = NetGroupEnum(NULL, 0, (LPBYTE*) &pGroups, MAX_PREFERRED_LENGTH, \
&dwEntriesRead, &dwTotalEntries, NULL); +
+    if (nStatus == NERR_Success) {
+        for (DWORD i = 0; i < dwEntriesRead; ++i) {
+            result.append(QString::fromUtf16((ushort *) pGroups[i].grpi0_name));
+        }
+    }
+
+    if (pGroups) {
+        NetApiBufferFree(pGroups);
+    }
+
+    return result;
+}
+
+KUserGroup::~KUserGroup()
+{
+}



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic