Add the general user properties page. Settings are visible but cannot be changed...
authorEric Kohl <eric.kohl@reactos.org>
Sun, 25 May 2008 11:50:56 +0000 (11:50 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 25 May 2008 11:50:56 +0000 (11:50 +0000)
svn path=/trunk/; revision=33696

reactos/dll/cpl/usrmgr/lang/en-US.rc
reactos/dll/cpl/usrmgr/resource.h
reactos/dll/cpl/usrmgr/userprops.c [new file with mode: 0644]
reactos/dll/cpl/usrmgr/users.c
reactos/dll/cpl/usrmgr/usrmgr.h
reactos/dll/cpl/usrmgr/usrmgr.rbuild

index a65faa4..95e87d2 100644 (file)
@@ -41,8 +41,16 @@ STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
 CAPTION "General"
 FONT 8, "MS Shell Dlg"
 BEGIN
-    LTEXT "", IDC_USER_NAME, 7, 7, 112, 8
-
+    LTEXT "", IDC_USER_GENERAL_NAME, 7, 7, 112, 8
+    LTEXT "Full name:", -1, 7, 46, 63, 8
+    EDITTEXT IDC_USER_GENERAL_FULL_NAME,77,43,168,13,ES_AUTOHSCROLL
+    LTEXT "Description:", -1, 7, 64, 63, 8
+    EDITTEXT IDC_USER_GENERAL_DESCRIPTION,77,61,168,13,ES_AUTOHSCROLL
+    AUTOCHECKBOX    "User must change the password upon first logon",IDC_USER_GENERAL_FORCE_CHANGE,7,82,210,10
+    AUTOCHECKBOX    "User cannot change the password",IDC_USER_GENERAL_CANNOT_CHANGE,7,95,210,10
+    AUTOCHECKBOX    "Password never expires",IDC_USER_GENERAL_NEVER_EXPIRES,7,108,210,10
+    AUTOCHECKBOX    "Account is disabled",IDC_USER_GENERAL_DISABLED,7,121,210,10
+    AUTOCHECKBOX    "Account is locked",IDC_USER_GENERAL_LOCKED,7,134,210,10,WS_DISABLED
 END
 
 
@@ -131,7 +139,7 @@ BEGIN
         MENUITEM "Delete", IDM_USER_DELETE
         MENUITEM "Rename", IDM_USER_RENAME
         MENUITEM SEPARATOR
-        MENUITEM "Properties", IDM_USER_PROPERTIES, GRAYED
+        MENUITEM "Properties", IDM_USER_PROPERTIES
     END
 END
 
index 7221855..f0050c5 100644 (file)
@@ -1,98 +1,98 @@
-#ifndef __CPL_USRMGR_RESOURCE_H__\r
-#define __CPL_USRMGR_RESOURCE_H__\r
-\r
-#include <commctrl.h>\r
-\r
-/* metrics */\r
-#define PROPSHEETWIDTH      246\r
-#define PROPSHEETHEIGHT     228\r
-#define PROPSHEETPADDING    6\r
-\r
-#define SYSTEM_COLUMN       (18 * PROPSHEETPADDING)\r
-#define LABELLINE(x)        (((PROPSHEETPADDING + 2) * x) + (x + 2))\r
-\r
-#define ICONSIZE            16\r
-\r
-\r
-/* Icons */\r
-#define IDI_USRMGR_ICON                 40\r
-#define IDI_USRMGR_ICON2                100 // Needed for theme compatibility with Windows.\r
-#define IDI_USER                        41\r
-#define IDI_LOCKED_USER                 42\r
-#define IDI_GROUP                       43\r
-\r
-\r
-#define IDD_USERS                       100\r
-#define IDD_GROUPS                      101\r
-#define IDD_EXTRA                       102\r
-\r
-#define IDC_USERS_LIST                  200\r
-\r
-#define IDC_GROUPS_LIST                 300\r
-\r
-#define IDC_STATIC                      -1\r
-\r
-\r
-/* Dialogs */\r
-\r
-#define IDD_USER_GENERAL            310\r
-#define IDC_USER_NAME               311\r
-#define IDC_USER_FULLNAME           312\r
-#define IDC_USER_DESCRIPTION        313\r
-#define IDC_USER_PW_CHANGE          314\r
-#define IDC_USER_PW_NOCHANGE        315\r
-#define IDC_USER_PW_EXPIRE          316\r
-#define IDC_USER_DEACTIVATE         317\r
-#define IDC_USER_LOCK               318\r
-\r
-\r
-#define IDD_CHANGE_PASSWORD         350\r
-#define IDC_EDIT_PASSWORD1          351\r
-#define IDC_EDIT_PASSWORD2          352\r
-\r
-\r
-#define IDD_USER_NEW                360\r
-#define IDC_USER_NEW_NAME           361\r
-#define IDC_USER_NEW_FULL_NAME      362\r
-#define IDC_USER_NEW_DESCRIPTION    363\r
-#define IDC_USER_NEW_PASSWORD1      364\r
-#define IDC_USER_NEW_PASSWORD2      365\r
-#define IDC_USER_NEW_FORCE_CHANGE   366\r
-#define IDC_USER_NEW_CANNOT_CHANGE  367\r
-#define IDC_USER_NEW_NEVER_EXPIRES  368\r
-#define IDC_USER_NEW_DISABLED       369\r
-\r
-\r
-#define IDD_GROUP_NEW               370\r
-#define IDC_GROUP_NEW_NAME          371\r
-#define IDC_GROUP_NEW_DESCRIPTION   372\r
-\r
-\r
-/* Strings */\r
-\r
-#define IDS_CPLNAME                 2000\r
-#define IDS_CPLDESCRIPTION          2001\r
-\r
-#define IDS_NAME                    2100\r
-#define IDS_FULLNAME                2101\r
-#define IDS_DESCRIPTION             2102\r
-\r
-\r
-/* Menus */\r
-\r
-#define IDM_POPUP_GROUP             120\r
-#define IDM_GROUP_ADD_MEMBER        121\r
-#define IDM_GROUP_NEW               122\r
-#define IDM_GROUP_DELETE            123\r
-#define IDM_GROUP_RENAME            124\r
-#define IDM_GROUP_PROPERTIES        125\r
-\r
-#define IDM_POPUP_USER              130\r
-#define IDM_USER_CHANGE_PASSWORD    131\r
-#define IDM_USER_NEW                132\r
-#define IDM_USER_DELETE             133\r
-#define IDM_USER_RENAME             134\r
-#define IDM_USER_PROPERTIES         135\r
-\r
-#endif /* __CPL_USRMGR_RESOURCE_H__ */\r
-\r
+#ifndef __CPL_USRMGR_RESOURCE_H__
+#define __CPL_USRMGR_RESOURCE_H__
+
+#include <commctrl.h>
+
+/* metrics */
+#define PROPSHEETWIDTH      246
+#define PROPSHEETHEIGHT     228
+#define PROPSHEETPADDING    6
+
+#define SYSTEM_COLUMN       (18 * PROPSHEETPADDING)
+#define LABELLINE(x)        (((PROPSHEETPADDING + 2) * x) + (x + 2))
+
+#define ICONSIZE            16
+
+
+/* Icons */
+#define IDI_USRMGR_ICON                 40
+#define IDI_USRMGR_ICON2                100 // Needed for theme compatibility with Windows.
+#define IDI_USER                        41
+#define IDI_LOCKED_USER                 42
+#define IDI_GROUP                       43
+
+
+#define IDD_USERS                       100
+#define IDD_GROUPS                      101
+#define IDD_EXTRA                       102
+
+#define IDC_USERS_LIST                  200
+
+#define IDC_GROUPS_LIST                 300
+
+#define IDC_STATIC                      -1
+
+
+/* Dialogs */
+
+#define IDD_USER_GENERAL               310
+#define IDC_USER_GENERAL_NAME          311
+#define IDC_USER_GENERAL_FULL_NAME     312
+#define IDC_USER_GENERAL_DESCRIPTION   313
+#define IDC_USER_GENERAL_FORCE_CHANGE  314
+#define IDC_USER_GENERAL_CANNOT_CHANGE 315
+#define IDC_USER_GENERAL_NEVER_EXPIRES 316
+#define IDC_USER_GENERAL_DISABLED      317
+#define IDC_USER_GENERAL_LOCKED        318
+
+
+#define IDD_CHANGE_PASSWORD         350
+#define IDC_EDIT_PASSWORD1          351
+#define IDC_EDIT_PASSWORD2          352
+
+
+#define IDD_USER_NEW                360
+#define IDC_USER_NEW_NAME           361
+#define IDC_USER_NEW_FULL_NAME      362
+#define IDC_USER_NEW_DESCRIPTION    363
+#define IDC_USER_NEW_PASSWORD1      364
+#define IDC_USER_NEW_PASSWORD2      365
+#define IDC_USER_NEW_FORCE_CHANGE   366
+#define IDC_USER_NEW_CANNOT_CHANGE  367
+#define IDC_USER_NEW_NEVER_EXPIRES  368
+#define IDC_USER_NEW_DISABLED       369
+
+
+#define IDD_GROUP_NEW               370
+#define IDC_GROUP_NEW_NAME          371
+#define IDC_GROUP_NEW_DESCRIPTION   372
+
+
+/* Strings */
+
+#define IDS_CPLNAME                 2000
+#define IDS_CPLDESCRIPTION          2001
+
+#define IDS_NAME                    2100
+#define IDS_FULLNAME                2101
+#define IDS_DESCRIPTION             2102
+
+
+/* Menus */
+
+#define IDM_POPUP_GROUP             120
+#define IDM_GROUP_ADD_MEMBER        121
+#define IDM_GROUP_NEW               122
+#define IDM_GROUP_DELETE            123
+#define IDM_GROUP_RENAME            124
+#define IDM_GROUP_PROPERTIES        125
+
+#define IDM_POPUP_USER              130
+#define IDM_USER_CHANGE_PASSWORD    131
+#define IDM_USER_NEW                132
+#define IDM_USER_DELETE             133
+#define IDM_USER_RENAME             134
+#define IDM_USER_PROPERTIES         135
+
+#endif /* __CPL_USRMGR_RESOURCE_H__ */
+
diff --git a/reactos/dll/cpl/usrmgr/userprops.c b/reactos/dll/cpl/usrmgr/userprops.c
new file mode 100644 (file)
index 0000000..736c83d
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS User Manager Control Panel
+ * FILE:            dll/cpl/usrmgr/users.c
+ * PURPOSE:         Users property page
+ *
+ * PROGRAMMERS:     Eric Kohl
+ */
+
+#include "usrmgr.h"
+
+static VOID
+UpdateUserOptions(HWND hwndDlg,
+                  PUSER_INFO_3 userInfo,
+                  BOOL bInit)
+{
+    EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_CANNOT_CHANGE),
+                 !userInfo->usri3_password_expired);
+    EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_NEVER_EXPIRES),
+                 !userInfo->usri3_password_expired);
+    EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_FORCE_CHANGE),
+                 (userInfo->usri3_flags & (UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD)) == 0);
+
+    if (bInit)
+    {
+        CheckDlgButton(hwndDlg, IDC_USER_GENERAL_FORCE_CHANGE,
+                       userInfo->usri3_password_expired ? BST_CHECKED : BST_UNCHECKED);
+
+        CheckDlgButton(hwndDlg, IDC_USER_GENERAL_CANNOT_CHANGE,
+                       (userInfo->usri3_flags & UF_PASSWD_CANT_CHANGE) ? BST_CHECKED : BST_UNCHECKED);
+
+        CheckDlgButton(hwndDlg, IDC_USER_GENERAL_NEVER_EXPIRES,
+                       (userInfo->usri3_flags & UF_DONT_EXPIRE_PASSWD) ? BST_CHECKED : BST_UNCHECKED);
+
+        CheckDlgButton(hwndDlg, IDC_USER_GENERAL_DISABLED,
+                       (userInfo->usri3_flags & UF_ACCOUNTDISABLE) ? BST_CHECKED : BST_UNCHECKED);
+    }
+}
+
+
+static VOID
+GetUserData(HWND hwndDlg, LPTSTR lpUserName, PUSER_INFO_3 *usrInfo)
+{
+    PUSER_INFO_3 userInfo = NULL;
+
+    SetDlgItemText(hwndDlg, IDC_USER_GENERAL_NAME, lpUserName);
+
+    NetUserGetInfo(NULL, lpUserName, 3, (LPBYTE*)&userInfo);
+
+    SetDlgItemText(hwndDlg, IDC_USER_GENERAL_FULL_NAME, userInfo->usri3_full_name);
+    SetDlgItemText(hwndDlg, IDC_USER_GENERAL_DESCRIPTION, userInfo->usri3_comment);
+
+    UpdateUserOptions(hwndDlg, userInfo, TRUE);
+
+    *usrInfo = userInfo;
+}
+
+
+INT_PTR CALLBACK
+UserGeneralPageProc(HWND hwndDlg,
+                    UINT uMsg,
+                    WPARAM wParam,
+                    LPARAM lParam)
+{
+    PUSER_INFO_3 userInfo;
+
+    UNREFERENCED_PARAMETER(lParam);
+    UNREFERENCED_PARAMETER(wParam);
+    UNREFERENCED_PARAMETER(hwndDlg);
+
+    userInfo = (PUSER_INFO_3)GetWindowLongPtr(hwndDlg, DWLP_USER);
+
+    switch (uMsg)
+    {
+        case WM_INITDIALOG:
+            GetUserData(hwndDlg,
+                        (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam,
+                        &userInfo);
+            SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)userInfo);
+            break;
+
+        case WM_COMMAND:
+            switch (LOWORD(wParam))
+            {
+                case IDC_USER_GENERAL_FORCE_CHANGE:
+                    userInfo->usri3_password_expired = !userInfo->usri3_password_expired;
+                    UpdateUserOptions(hwndDlg, userInfo, FALSE);
+                    break;
+
+                case IDC_USER_GENERAL_CANNOT_CHANGE:
+                    userInfo->usri3_flags ^= UF_PASSWD_CANT_CHANGE;
+                    UpdateUserOptions(hwndDlg, userInfo, FALSE);
+                    break;
+
+                case IDC_USER_GENERAL_NEVER_EXPIRES:
+                    userInfo->usri3_flags ^= UF_DONT_EXPIRE_PASSWD;
+                    UpdateUserOptions(hwndDlg, userInfo, FALSE);
+                    break;
+
+                case IDC_USER_GENERAL_DISABLED:
+                    userInfo->usri3_flags ^= UF_ACCOUNTDISABLE;
+                    break;
+
+                case IDC_USER_GENERAL_LOCKED:
+                    break;
+            }
+            break;
+
+        case WM_DESTROY:
+            NetApiBufferFree(userInfo);
+            break;
+    }
+
+    return FALSE;
+}
+
+
+static VOID
+InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc, LPTSTR pszUser)
+{
+    ZeroMemory(psp, sizeof(PROPSHEETPAGE));
+    psp->dwSize = sizeof(PROPSHEETPAGE);
+    psp->dwFlags = PSP_DEFAULT;
+    psp->hInstance = hApplet;
+    psp->pszTemplate = MAKEINTRESOURCE(idDlg);
+    psp->pfnDlgProc = DlgProc;
+    psp->lParam = (LPARAM)pszUser;
+}
+
+
+VOID
+UserProperties(HWND hwndDlg)
+{
+    PROPSHEETPAGE psp[1];
+    PROPSHEETHEADER psh;
+    TCHAR szUserName[UNLEN];
+    INT nItem;
+    HWND hwndLV;
+
+    hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
+    nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
+    if (nItem == -1)
+        return;
+
+    /* Get the new user name */
+    ListView_GetItemText(hwndLV,
+                         nItem, 0,
+                         szUserName,
+                         UNLEN);
+
+    ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
+    psh.dwSize = sizeof(PROPSHEETHEADER);
+    psh.dwFlags =  PSH_PROPSHEETPAGE | PSH_PROPTITLE;
+    psh.hwndParent = hwndDlg;
+    psh.hInstance = hApplet;
+    psh.hIcon = NULL;
+    psh.pszCaption = szUserName;
+    psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
+    psh.nStartPage = 0;
+    psh.ppsp = psp;
+
+    InitPropSheetPage(&psp[0], IDD_USER_GENERAL, (DLGPROC)UserGeneralPageProc, szUserName);
+//    InitPropSheetPage(&psp[1], IDD_USER_MEMBERSHIP, (DLGPROC)UserMembershipPageProc);
+//    InitPropSheetPage(&psp[2], IDD_USER_PROFILE, (DLGPROC)UserProfilePageProc);
+
+    PropertySheet(&psh);
+}
index d10e7fe..8dfdc16 100644 (file)
-/*\r
- * COPYRIGHT:       See COPYING in the top level directory\r
- * PROJECT:         ReactOS User Manager Control Panel\r
- * FILE:            dll/cpl/usrmgr/users.c\r
- * PURPOSE:         Users property page\r
- *\r
- * PROGRAMMERS:     Eric Kohl\r
- */\r
-\r
-/*\r
- * TODO:\r
- *  - Add new user to the users group.\r
- *  - Remove a user from all groups.\r
- *  - Implement user property pages.\r
- *  - Use localized messages.\r
- */\r
-\r
-#include "usrmgr.h"\r
-\r
-\r
-typedef struct _USER_DATA\r
-{\r
-    HMENU hPopupMenu;\r
-\r
-    INT iCurrentItem;\r
-\r
-} USER_DATA, *PUSER_DATA;\r
-\r
-\r
-\r
-static BOOL\r
-CheckPasswords(HWND hwndDlg,\r
-               INT nIdDlgItem1,\r
-               INT nIdDlgItem2)\r
-{\r
-    TCHAR szPassword1[256];\r
-    TCHAR szPassword2[256];\r
-    UINT uLen1;\r
-    UINT uLen2;\r
-\r
-    uLen1 = GetDlgItemText(hwndDlg, nIdDlgItem1, szPassword1, 256);\r
-    uLen2 = GetDlgItemText(hwndDlg, nIdDlgItem2, szPassword2, 256);\r
-\r
-    /* Check the passwords */\r
-    if (uLen1 != uLen2 || _tcscmp(szPassword1, szPassword2) != 0)\r
-    {\r
-        MessageBox(hwndDlg,\r
-                   TEXT("The passwords you entered are not the same!"),\r
-                   TEXT("ERROR"),\r
-                   MB_OK | MB_ICONERROR);\r
-        return FALSE;\r
-    }\r
-\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-INT_PTR CALLBACK\r
-ChangePasswordDlgProc(HWND hwndDlg,\r
-                      UINT uMsg,\r
-                      WPARAM wParam,\r
-                      LPARAM lParam)\r
-{\r
-    UNREFERENCED_PARAMETER(wParam);\r
-\r
-    switch (uMsg)\r
-    {\r
-        case WM_INITDIALOG:\r
-            break;\r
-\r
-        case WM_COMMAND:\r
-            switch (LOWORD(wParam))\r
-            {\r
-                case IDOK:\r
-                    if (CheckPasswords(hwndDlg, IDC_EDIT_PASSWORD1, IDC_EDIT_PASSWORD2))\r
-                        EndDialog(hwndDlg, 0);\r
-                    break;\r
-\r
-                case IDCANCEL:\r
-                    EndDialog(hwndDlg, 0);\r
-                    break;\r
-            }\r
-            break;\r
-\r
-        default:\r
-            return FALSE;\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-static VOID\r
-UpdateUserOptions(HWND hwndDlg,\r
-                  PUSER_INFO_3 userInfo,\r
-                  BOOL bInit)\r
-{\r
-    EnableWindow(GetDlgItem(hwndDlg, IDC_USER_NEW_CANNOT_CHANGE),\r
-                 !userInfo->usri3_password_expired);\r
-    EnableWindow(GetDlgItem(hwndDlg, IDC_USER_NEW_NEVER_EXPIRES),\r
-                 !userInfo->usri3_password_expired);\r
-\r
-    EnableWindow(GetDlgItem(hwndDlg, IDC_USER_NEW_FORCE_CHANGE),\r
-                 (userInfo->usri3_flags & (UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD)) == 0);\r
-\r
-    if (bInit)\r
-    {\r
-        CheckDlgButton(hwndDlg, IDC_USER_NEW_FORCE_CHANGE,\r
-                       userInfo->usri3_password_expired ? BST_CHECKED : BST_UNCHECKED);\r
-\r
-        CheckDlgButton(hwndDlg, IDC_USER_NEW_CANNOT_CHANGE,\r
-                       (userInfo->usri3_flags & UF_PASSWD_CANT_CHANGE) ? BST_CHECKED : BST_UNCHECKED);\r
-\r
-        CheckDlgButton(hwndDlg, IDC_USER_NEW_NEVER_EXPIRES,\r
-                       (userInfo->usri3_flags & UF_DONT_EXPIRE_PASSWD) ? BST_CHECKED : BST_UNCHECKED);\r
-\r
-        CheckDlgButton(hwndDlg, IDC_USER_NEW_DISABLED,\r
-                       (userInfo->usri3_flags & UF_ACCOUNTDISABLE) ? BST_CHECKED : BST_UNCHECKED);\r
-    }\r
-}\r
-\r
-\r
-INT_PTR CALLBACK\r
-NewUserDlgProc(HWND hwndDlg,\r
-               UINT uMsg,\r
-               WPARAM wParam,\r
-               LPARAM lParam)\r
-{\r
-    PUSER_INFO_3 userInfo;\r
-    INT nLength;\r
-\r
-    UNREFERENCED_PARAMETER(wParam);\r
-\r
-    userInfo = (PUSER_INFO_3)GetWindowLongPtr(hwndDlg, DWLP_USER);\r
-\r
-    switch (uMsg)\r
-    {\r
-        case WM_INITDIALOG:\r
-            userInfo = (PUSER_INFO_3)lParam;\r
-            SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);\r
-            SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, EM_SETLIMITTEXT, 20, 0);\r
-            UpdateUserOptions(hwndDlg, userInfo, TRUE);\r
-            break;\r
-\r
-        case WM_COMMAND:\r
-            switch (LOWORD(wParam))\r
-            {\r
-                case IDC_USER_NEW_NAME:\r
-                    if (HIWORD(wParam) == EN_CHANGE)\r
-                    {\r
-                        nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, WM_GETTEXTLENGTH, 0, 0);\r
-                        EnableWindow(GetDlgItem(hwndDlg, IDOK), (nLength > 0));\r
-                    }\r
-                    break;\r
-\r
-                case IDC_USER_NEW_FORCE_CHANGE:\r
-                    userInfo->usri3_password_expired = !userInfo->usri3_password_expired;\r
-                    UpdateUserOptions(hwndDlg, userInfo, FALSE);\r
-                    break;\r
-\r
-                case IDC_USER_NEW_CANNOT_CHANGE:\r
-                    userInfo->usri3_flags ^= UF_PASSWD_CANT_CHANGE;\r
-                    UpdateUserOptions(hwndDlg, userInfo, FALSE);\r
-                    break;\r
-\r
-                case IDC_USER_NEW_NEVER_EXPIRES:\r
-                    userInfo->usri3_flags ^= UF_DONT_EXPIRE_PASSWD;\r
-                    UpdateUserOptions(hwndDlg, userInfo, FALSE);\r
-                    break;\r
-\r
-                case IDC_USER_NEW_DISABLED:\r
-                    userInfo->usri3_flags ^= UF_ACCOUNTDISABLE;\r
-                    break;\r
-\r
-                case IDOK:\r
-                    if (!CheckAccountName(hwndDlg, IDC_USER_NEW_NAME, NULL))\r
-                    {\r
-                        SetFocus(GetDlgItem(hwndDlg, IDC_USER_NEW_NAME));\r
-                        SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, EM_SETSEL, 0, -1);\r
-                        break;\r
-                    }\r
-\r
-                    if (!CheckPasswords(hwndDlg, IDC_USER_NEW_PASSWORD1, IDC_USER_NEW_PASSWORD2))\r
-                    {\r
-                        SetDlgItemText(hwndDlg, IDC_USER_NEW_PASSWORD1, TEXT(""));\r
-                        SetDlgItemText(hwndDlg, IDC_USER_NEW_PASSWORD2, TEXT(""));\r
-                        break;\r
-                    }\r
-\r
-                    /* Store the user name */\r
-                    nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, WM_GETTEXTLENGTH, 0, 0);\r
-                    if (nLength > 0)\r
-                    {\r
-                        userInfo->usri3_name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));\r
-                        GetDlgItemText(hwndDlg, IDC_USER_NEW_NAME, userInfo->usri3_name, nLength + 1);\r
-                    }\r
-\r
-                    /* Store the full user name */\r
-                    nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_FULL_NAME, WM_GETTEXTLENGTH, 0, 0);\r
-                    if (nLength > 0)\r
-                    {\r
-                        userInfo->usri3_full_name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));\r
-                        GetDlgItemText(hwndDlg, IDC_USER_NEW_FULL_NAME, userInfo->usri3_full_name, nLength + 1);\r
-                    }\r
-\r
-                    /* Store the description */\r
-                    nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_DESCRIPTION, WM_GETTEXTLENGTH, 0, 0);\r
-                    if (nLength > 0)\r
-                    {\r
-                        userInfo->usri3_comment = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));\r
-                        GetDlgItemText(hwndDlg, IDC_USER_NEW_DESCRIPTION, userInfo->usri3_comment, nLength + 1);\r
-                    }\r
-\r
-                    /* Store the password */\r
-                    nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_PASSWORD1, WM_GETTEXTLENGTH, 0, 0);\r
-                    if (nLength > 0)\r
-                    {\r
-                        userInfo->usri3_password = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));\r
-                        GetDlgItemText(hwndDlg, IDC_USER_NEW_PASSWORD1, userInfo->usri3_password, nLength + 1);\r
-                    }\r
-\r
-                    EndDialog(hwndDlg, IDOK);\r
-                    break;\r
-\r
-                case IDCANCEL:\r
-                    EndDialog(hwndDlg, IDCANCEL);\r
-                    break;\r
-            }\r
-            break;\r
-\r
-        default:\r
-            return FALSE;\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-static VOID\r
-UserNew(HWND hwndDlg)\r
-{\r
-    USER_INFO_3 user;\r
-    NET_API_STATUS status;\r
-    LV_ITEM lvi;\r
-    INT iItem;\r
-    HWND hwndLV;\r
-\r
-    ZeroMemory(&user, sizeof(USER_INFO_3));\r
-\r
-    user.usri3_priv = USER_PRIV_USER;\r
-    user.usri3_flags = UF_SCRIPT;\r
-    user.usri3_acct_expires = TIMEQ_FOREVER;\r
-    user.usri3_max_storage = USER_MAXSTORAGE_UNLIMITED;\r
-    user.usri3_primary_group_id = DOMAIN_GROUP_RID_USERS;\r
-\r
-    user.usri3_password_expired = TRUE;\r
-\r
-    if (DialogBoxParam(hApplet,\r
-                       MAKEINTRESOURCE(IDD_USER_NEW),\r
-                       hwndDlg,\r
-                       NewUserDlgProc,\r
-                       (LPARAM)&user) == IDOK)\r
-    {\r
-#if 0\r
-        status = NetUserAdd(NULL,\r
-                            3,\r
-                            (LPBYTE)&user,\r
-                            NULL);\r
-#else\r
-        status = NERR_Success;\r
-#endif\r
-        if (status != NERR_Success)\r
-        {\r
-            TCHAR szText[256];\r
-            wsprintf(szText, TEXT("Error: %u"), status);\r
-            MessageBox(NULL, szText, TEXT("NetUserAdd"), MB_ICONERROR | MB_OK);\r
-            return;\r
-        }\r
-\r
-        hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);\r
-\r
-        ZeroMemory(&lvi, sizeof(lvi));\r
-        lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;\r
-        lvi.pszText = user.usri3_name;\r
-        lvi.state = 0;\r
-        lvi.iImage = (user.usri3_flags & UF_ACCOUNTDISABLE) ? 1 : 0;\r
-        iItem = ListView_InsertItem(hwndLV, &lvi);\r
-\r
-        ListView_SetItemText(hwndLV, iItem, 1,\r
-                             user.usri3_full_name);\r
-\r
-        ListView_SetItemText(hwndLV, iItem, 2,\r
-                             user.usri3_comment);\r
-    }\r
-\r
-    if (user.usri3_name)\r
-        HeapFree(GetProcessHeap, 0, user.usri3_name);\r
-\r
-    if (user.usri3_full_name)\r
-        HeapFree(GetProcessHeap, 0, user.usri3_full_name);\r
-\r
-    if (user.usri3_comment)\r
-        HeapFree(GetProcessHeap, 0, user.usri3_comment);\r
-\r
-    if (user.usri3_password)\r
-        HeapFree(GetProcessHeap, 0, user.usri3_password);\r
-}\r
-\r
-\r
-static VOID\r
-UserRename(HWND hwndDlg)\r
-{\r
-    HWND hwndLV;\r
-    INT nItem;\r
-\r
-    hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);\r
-    if (hwndLV == NULL)\r
-        return;\r
-\r
-    nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);\r
-    if (nItem != -1)\r
-    {\r
-        (void)ListView_EditLabel(hwndLV, nItem);\r
-    }\r
-}\r
-\r
-\r
-static BOOL\r
-UserDelete(HWND hwndDlg)\r
-{\r
-    TCHAR szUserName[UNLEN];\r
-    TCHAR szText[256];\r
-    INT nItem;\r
-    HWND hwndLV;\r
-    NET_API_STATUS status;\r
-\r
-    hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);\r
-    nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);\r
-    if (nItem == -1)\r
-        return FALSE;\r
-\r
-    /* Get the new user name */\r
-    ListView_GetItemText(hwndLV,\r
-                         nItem, 0,\r
-                         szUserName,\r
-                         UNLEN);\r
-\r
-    /* Display a warning message because the delete operation cannot be reverted */\r
-    wsprintf(szText, TEXT("Dou you really want to delete the user \"%s\"?"), szUserName);\r
-    if (MessageBox(NULL, szText, TEXT("User Accounts"), MB_ICONWARNING | MB_YESNO) == IDNO)\r
-        return FALSE;\r
-\r
-    /* Delete the user */\r
-#if 0\r
-    status = NetUserDel(NULL, szUserName);\r
-#else\r
-    status = NERR_Success;\r
-#endif\r
-    if (status != NERR_Success)\r
-    {\r
-        TCHAR szText[256];\r
-        wsprintf(szText, TEXT("Error: %u"), status);\r
-        MessageBox(NULL, szText, TEXT("NetUserDel"), MB_ICONERROR | MB_OK);\r
-        return FALSE;\r
-    }\r
-\r
-    /* Delete the user from the list */\r
-    (void)ListView_DeleteItem(hwndLV, nItem);\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-static VOID\r
-SetUsersListColumns(HWND hwndListView)\r
-{\r
-    LV_COLUMN column;\r
-    RECT rect;\r
-    TCHAR szStr[32];\r
-\r
-    GetClientRect(hwndListView, &rect);\r
-\r
-    memset(&column, 0x00, sizeof(column));\r
-    column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;\r
-    column.fmt=LVCFMT_LEFT;\r
-    column.cx = (INT)((rect.right - rect.left) * 0.25);\r
-    column.iSubItem = 0;\r
-    LoadString(hApplet, IDS_NAME, szStr, sizeof(szStr) / sizeof(szStr[0]));\r
-    column.pszText = szStr;\r
-    (void)ListView_InsertColumn(hwndListView, 0, &column);\r
-\r
-    column.cx = (INT)((rect.right - rect.left) * 0.50);\r
-    column.iSubItem = 1;\r
-    LoadString(hApplet, IDS_FULLNAME, szStr, sizeof(szStr) / sizeof(szStr[0]));\r
-    column.pszText = szStr;\r
-    (void)ListView_InsertColumn(hwndListView, 1, &column);\r
-\r
-    column.cx = (INT)((rect.right - rect.left) * 0.25);\r
-    column.iSubItem = 2;\r
-    LoadString(hApplet, IDS_DESCRIPTION, szStr, sizeof(szStr) / sizeof(szStr[0]));\r
-    column.pszText = szStr;\r
-    (void)ListView_InsertColumn(hwndListView, 2, &column);\r
-}\r
-\r
-\r
-static VOID\r
-UpdateUsersList(HWND hwndListView)\r
-{\r
-    NET_API_STATUS netStatus;\r
-    PUSER_INFO_20 pBuffer;\r
-    DWORD entriesread;\r
-    DWORD totalentries;\r
-    DWORD resume_handle = 0;\r
-    DWORD i;\r
-    LV_ITEM lvi;\r
-    INT iItem;\r
-\r
-\r
-    for (;;)\r
-    {\r
-        netStatus = NetUserEnum(NULL, 20, FILTER_NORMAL_ACCOUNT,\r
-                                (LPBYTE*)&pBuffer,\r
-                                1024, &entriesread,\r
-                                &totalentries, &resume_handle);\r
-        if (netStatus != NERR_Success && netStatus != ERROR_MORE_DATA)\r
-            break;\r
-\r
-        for (i = 0; i < entriesread; i++)\r
-        {\r
-           memset(&lvi, 0x00, sizeof(lvi));\r
-           lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;\r
-           lvi.pszText = pBuffer[i].usri20_name;\r
-           lvi.state = 0;\r
-           lvi.iImage = (pBuffer[i].usri20_flags & UF_ACCOUNTDISABLE) ? 1 : 0;\r
-           iItem = ListView_InsertItem(hwndListView, &lvi);\r
-\r
-           ListView_SetItemText(hwndListView, iItem, 1,\r
-                                pBuffer[i].usri20_full_name);\r
-\r
-           ListView_SetItemText(hwndListView, iItem, 2,\r
-                                pBuffer[i].usri20_comment);\r
-        }\r
-\r
-        NetApiBufferFree(&pBuffer);\r
-\r
-        /* No more data left */\r
-        if (netStatus != ERROR_MORE_DATA)\r
-            break;\r
-    }\r
-\r
-}\r
-\r
-\r
-static VOID\r
-OnInitDialog(HWND hwndDlg)\r
-{\r
-    HWND hwndListView;\r
-    HIMAGELIST hImgList;\r
-    HICON hIcon;\r
-\r
-    /* Create the image list */\r
-    hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 5, 5);\r
-    hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_USER), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);\r
-    ImageList_AddIcon(hImgList, hIcon);\r
-    hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_LOCKED_USER), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);\r
-    ImageList_AddIcon(hImgList, hIcon);\r
-    DestroyIcon(hIcon);\r
-\r
-    hwndListView = GetDlgItem(hwndDlg, IDC_USERS_LIST);\r
-\r
-    (VOID)ListView_SetImageList(hwndListView, hImgList, LVSIL_SMALL);\r
-\r
-    (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT);\r
-\r
-    SetUsersListColumns(hwndListView);\r
-\r
-    UpdateUsersList(hwndListView);\r
-}\r
-\r
-\r
-static BOOL\r
-OnBeginLabelEdit(LPNMLVDISPINFO pnmv)\r
-{\r
-    HWND hwndEdit;\r
-\r
-    hwndEdit = ListView_GetEditControl(pnmv->hdr.hwndFrom);\r
-    if (hwndEdit == NULL)\r
-        return TRUE;\r
-\r
-    SendMessage(hwndEdit, EM_SETLIMITTEXT, 20, 0);\r
-\r
-    return FALSE;\r
-}\r
-\r
-\r
-static BOOL\r
-OnEndLabelEdit(LPNMLVDISPINFO pnmv)\r
-{\r
-    TCHAR szOldUserName[UNLEN];\r
-    TCHAR szNewUserName[UNLEN];\r
-    USER_INFO_0 useri0;\r
-    NET_API_STATUS status;\r
-\r
-    /* Leave, if there is no valid listview item */\r
-    if (pnmv->item.iItem == -1)\r
-        return FALSE;\r
-\r
-    /* Get the new user name */\r
-    ListView_GetItemText(pnmv->hdr.hwndFrom,\r
-                         pnmv->item.iItem, 0,\r
-                         szOldUserName,\r
-                         UNLEN);\r
-\r
-    /* Leave, if the user canceled the edit action */\r
-    if (pnmv->item.pszText == NULL)\r
-        return FALSE;\r
-\r
-    /* Get the new user name */\r
-    lstrcpy(szNewUserName, pnmv->item.pszText);\r
-\r
-    /* Leave, if the user name was not changed */\r
-    if (lstrcmp(szOldUserName, szNewUserName) == 0)\r
-        return FALSE;\r
-\r
-    /* Check the user name for illegal characters */\r
-    if (!CheckAccountName(NULL, 0, szNewUserName))\r
-        return FALSE;\r
-\r
-    /* Change the user name */\r
-    useri0.usri0_name = szNewUserName;\r
-\r
-#if 0\r
-    status = NetUserSetInfo(NULL, szOldUserName, 0, (LPBYTE)&useri0, NULL);\r
-#else\r
-    status = NERR_Success;\r
-#endif\r
-    if (status != NERR_Success)\r
-    {\r
-        TCHAR szText[256];\r
-        wsprintf(szText, TEXT("Error: %u"), status);\r
-        MessageBox(NULL, szText, TEXT("NetUserSetInfo"), MB_ICONERROR | MB_OK);\r
-        return FALSE;\r
-    }\r
-\r
-    /* Update the listview item */\r
-    ListView_SetItemText(pnmv->hdr.hwndFrom,\r
-                         pnmv->item.iItem, 0,\r
-                         szNewUserName);\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-static BOOL\r
-OnNotify(HWND hwndDlg, PUSER_DATA pUserData, NMHDR *phdr)\r
-{\r
-    LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;\r
-\r
-    switch (phdr->idFrom)\r
-    {\r
-        case IDC_USERS_LIST:\r
-            switch(phdr->code)\r
-            {\r
-                case NM_CLICK:\r
-                    pUserData->iCurrentItem = lpnmlv->iItem;\r
-                    if (lpnmlv->iItem == -1)\r
-                    {\r
-                    }\r
-                    else\r
-                    {\r
-                    }\r
-                    break;\r
-\r
-                case NM_DBLCLK:\r
-                    break;\r
-\r
-                case NM_RCLICK:\r
-                    ClientToScreen(GetDlgItem(hwndDlg, IDC_USERS_LIST), &lpnmlv->ptAction);\r
-                    TrackPopupMenu(GetSubMenu(pUserData->hPopupMenu, (lpnmlv->iItem == -1) ? 0 : 1),\r
-                                   TPM_LEFTALIGN, lpnmlv->ptAction.x, lpnmlv->ptAction.y, 0, hwndDlg, NULL);\r
-                    break;\r
-\r
-                case LVN_BEGINLABELEDIT:\r
-                    return OnBeginLabelEdit((LPNMLVDISPINFO)phdr);\r
-\r
-                case LVN_ENDLABELEDIT:\r
-                    return OnEndLabelEdit((LPNMLVDISPINFO)phdr);\r
-            }\r
-            break;\r
-    }\r
-\r
-    return FALSE;\r
-}\r
-\r
-\r
-INT_PTR CALLBACK\r
-UsersPageProc(HWND hwndDlg,\r
-              UINT uMsg,\r
-              WPARAM wParam,\r
-              LPARAM lParam)\r
-{\r
-    PUSER_DATA pUserData;\r
-\r
-    UNREFERENCED_PARAMETER(wParam);\r
-\r
-    pUserData = (PUSER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);\r
-\r
-    switch (uMsg)\r
-    {\r
-        case WM_INITDIALOG:\r
-            pUserData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(USER_DATA));\r
-            SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pUserData);\r
-\r
-            pUserData->hPopupMenu = LoadMenu(hApplet, MAKEINTRESOURCE(IDM_POPUP_USER));\r
-\r
-            OnInitDialog(hwndDlg);\r
-            break;\r
-\r
-        case WM_COMMAND:\r
-            switch (LOWORD(wParam))\r
-            {\r
-                case IDM_USER_CHANGE_PASSWORD:\r
-                    DialogBoxParam(hApplet,\r
-                                   MAKEINTRESOURCE(IDD_CHANGE_PASSWORD),\r
-                                   hwndDlg,\r
-                                   ChangePasswordDlgProc,\r
-                                   (LPARAM)NULL);\r
-                    break;\r
-\r
-                case IDM_USER_RENAME:\r
-                    UserRename(hwndDlg);\r
-                    break;\r
-\r
-                case IDM_USER_NEW:\r
-                    UserNew(hwndDlg);\r
-                    break;\r
-\r
-                case IDM_USER_DELETE:\r
-                    UserDelete(hwndDlg);\r
-                    break;\r
-\r
-                case IDM_USER_PROPERTIES:\r
-                    MessageBeep(-1);\r
-                    break;\r
-            }\r
-            break;\r
-\r
-        case WM_NOTIFY:\r
-            return OnNotify(hwndDlg, pUserData, (NMHDR *)lParam);\r
-\r
-        case WM_DESTROY:\r
-            DestroyMenu(pUserData->hPopupMenu);\r
-            HeapFree(GetProcessHeap(), 0, pUserData);\r
-            break;\r
-    }\r
-\r
-    return FALSE;\r
-}\r
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS User Manager Control Panel
+ * FILE:            dll/cpl/usrmgr/users.c
+ * PURPOSE:         Users property page
+ *
+ * PROGRAMMERS:     Eric Kohl
+ */
+
+/*
+ * TODO:
+ *  - Add new user to the users group.
+ *  - Remove a user from all groups.
+ *  - Use localized messages.
+ */
+
+#include "usrmgr.h"
+
+
+typedef struct _USER_DATA
+{
+    HMENU hPopupMenu;
+
+    INT iCurrentItem;
+
+} USER_DATA, *PUSER_DATA;
+
+
+
+static BOOL
+CheckPasswords(HWND hwndDlg,
+               INT nIdDlgItem1,
+               INT nIdDlgItem2)
+{
+    TCHAR szPassword1[256];
+    TCHAR szPassword2[256];
+    UINT uLen1;
+    UINT uLen2;
+
+    uLen1 = GetDlgItemText(hwndDlg, nIdDlgItem1, szPassword1, 256);
+    uLen2 = GetDlgItemText(hwndDlg, nIdDlgItem2, szPassword2, 256);
+
+    /* Check the passwords */
+    if (uLen1 != uLen2 || _tcscmp(szPassword1, szPassword2) != 0)
+    {
+        MessageBox(hwndDlg,
+                   TEXT("The passwords you entered are not the same!"),
+                   TEXT("ERROR"),
+                   MB_OK | MB_ICONERROR);
+        return FALSE;
+    }
+
+
+    return TRUE;
+}
+
+
+INT_PTR CALLBACK
+ChangePasswordDlgProc(HWND hwndDlg,
+                      UINT uMsg,
+                      WPARAM wParam,
+                      LPARAM lParam)
+{
+    UNREFERENCED_PARAMETER(wParam);
+
+    switch (uMsg)
+    {
+        case WM_INITDIALOG:
+            break;
+
+        case WM_COMMAND:
+            switch (LOWORD(wParam))
+            {
+                case IDOK:
+                    if (CheckPasswords(hwndDlg, IDC_EDIT_PASSWORD1, IDC_EDIT_PASSWORD2))
+                        EndDialog(hwndDlg, 0);
+                    break;
+
+                case IDCANCEL:
+                    EndDialog(hwndDlg, 0);
+                    break;
+            }
+            break;
+
+        default:
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+
+static VOID
+UpdateUserOptions(HWND hwndDlg,
+                  PUSER_INFO_3 userInfo,
+                  BOOL bInit)
+{
+    EnableWindow(GetDlgItem(hwndDlg, IDC_USER_NEW_CANNOT_CHANGE),
+                 !userInfo->usri3_password_expired);
+    EnableWindow(GetDlgItem(hwndDlg, IDC_USER_NEW_NEVER_EXPIRES),
+                 !userInfo->usri3_password_expired);
+
+    EnableWindow(GetDlgItem(hwndDlg, IDC_USER_NEW_FORCE_CHANGE),
+                 (userInfo->usri3_flags & (UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD)) == 0);
+
+    if (bInit)
+    {
+        CheckDlgButton(hwndDlg, IDC_USER_NEW_FORCE_CHANGE,
+                       userInfo->usri3_password_expired ? BST_CHECKED : BST_UNCHECKED);
+
+        CheckDlgButton(hwndDlg, IDC_USER_NEW_CANNOT_CHANGE,
+                       (userInfo->usri3_flags & UF_PASSWD_CANT_CHANGE) ? BST_CHECKED : BST_UNCHECKED);
+
+        CheckDlgButton(hwndDlg, IDC_USER_NEW_NEVER_EXPIRES,
+                       (userInfo->usri3_flags & UF_DONT_EXPIRE_PASSWD) ? BST_CHECKED : BST_UNCHECKED);
+
+        CheckDlgButton(hwndDlg, IDC_USER_NEW_DISABLED,
+                       (userInfo->usri3_flags & UF_ACCOUNTDISABLE) ? BST_CHECKED : BST_UNCHECKED);
+    }
+}
+
+
+INT_PTR CALLBACK
+NewUserDlgProc(HWND hwndDlg,
+               UINT uMsg,
+               WPARAM wParam,
+               LPARAM lParam)
+{
+    PUSER_INFO_3 userInfo;
+    INT nLength;
+
+    UNREFERENCED_PARAMETER(wParam);
+
+    userInfo = (PUSER_INFO_3)GetWindowLongPtr(hwndDlg, DWLP_USER);
+
+    switch (uMsg)
+    {
+        case WM_INITDIALOG:
+            userInfo = (PUSER_INFO_3)lParam;
+            SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
+            SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, EM_SETLIMITTEXT, 20, 0);
+            UpdateUserOptions(hwndDlg, userInfo, TRUE);
+            break;
+
+        case WM_COMMAND:
+            switch (LOWORD(wParam))
+            {
+                case IDC_USER_NEW_NAME:
+                    if (HIWORD(wParam) == EN_CHANGE)
+                    {
+                        nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, WM_GETTEXTLENGTH, 0, 0);
+                        EnableWindow(GetDlgItem(hwndDlg, IDOK), (nLength > 0));
+                    }
+                    break;
+
+                case IDC_USER_NEW_FORCE_CHANGE:
+                    userInfo->usri3_password_expired = !userInfo->usri3_password_expired;
+                    UpdateUserOptions(hwndDlg, userInfo, FALSE);
+                    break;
+
+                case IDC_USER_NEW_CANNOT_CHANGE:
+                    userInfo->usri3_flags ^= UF_PASSWD_CANT_CHANGE;
+                    UpdateUserOptions(hwndDlg, userInfo, FALSE);
+                    break;
+
+                case IDC_USER_NEW_NEVER_EXPIRES:
+                    userInfo->usri3_flags ^= UF_DONT_EXPIRE_PASSWD;
+                    UpdateUserOptions(hwndDlg, userInfo, FALSE);
+                    break;
+
+                case IDC_USER_NEW_DISABLED:
+                    userInfo->usri3_flags ^= UF_ACCOUNTDISABLE;
+                    break;
+
+                case IDOK:
+                    if (!CheckAccountName(hwndDlg, IDC_USER_NEW_NAME, NULL))
+                    {
+                        SetFocus(GetDlgItem(hwndDlg, IDC_USER_NEW_NAME));
+                        SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, EM_SETSEL, 0, -1);
+                        break;
+                    }
+
+                    if (!CheckPasswords(hwndDlg, IDC_USER_NEW_PASSWORD1, IDC_USER_NEW_PASSWORD2))
+                    {
+                        SetDlgItemText(hwndDlg, IDC_USER_NEW_PASSWORD1, TEXT(""));
+                        SetDlgItemText(hwndDlg, IDC_USER_NEW_PASSWORD2, TEXT(""));
+                        break;
+                    }
+
+                    /* Store the user name */
+                    nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, WM_GETTEXTLENGTH, 0, 0);
+                    if (nLength > 0)
+                    {
+                        userInfo->usri3_name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));
+                        GetDlgItemText(hwndDlg, IDC_USER_NEW_NAME, userInfo->usri3_name, nLength + 1);
+                    }
+
+                    /* Store the full user name */
+                    nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_FULL_NAME, WM_GETTEXTLENGTH, 0, 0);
+                    if (nLength > 0)
+                    {
+                        userInfo->usri3_full_name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));
+                        GetDlgItemText(hwndDlg, IDC_USER_NEW_FULL_NAME, userInfo->usri3_full_name, nLength + 1);
+                    }
+
+                    /* Store the description */
+                    nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_DESCRIPTION, WM_GETTEXTLENGTH, 0, 0);
+                    if (nLength > 0)
+                    {
+                        userInfo->usri3_comment = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));
+                        GetDlgItemText(hwndDlg, IDC_USER_NEW_DESCRIPTION, userInfo->usri3_comment, nLength + 1);
+                    }
+
+                    /* Store the password */
+                    nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_PASSWORD1, WM_GETTEXTLENGTH, 0, 0);
+                    if (nLength > 0)
+                    {
+                        userInfo->usri3_password = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));
+                        GetDlgItemText(hwndDlg, IDC_USER_NEW_PASSWORD1, userInfo->usri3_password, nLength + 1);
+                    }
+
+                    EndDialog(hwndDlg, IDOK);
+                    break;
+
+                case IDCANCEL:
+                    EndDialog(hwndDlg, IDCANCEL);
+                    break;
+            }
+            break;
+
+        default:
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+
+static VOID
+UserNew(HWND hwndDlg)
+{
+    USER_INFO_3 user;
+    NET_API_STATUS status;
+    LV_ITEM lvi;
+    INT iItem;
+    HWND hwndLV;
+
+    ZeroMemory(&user, sizeof(USER_INFO_3));
+
+    user.usri3_priv = USER_PRIV_USER;
+    user.usri3_flags = UF_SCRIPT;
+    user.usri3_acct_expires = TIMEQ_FOREVER;
+    user.usri3_max_storage = USER_MAXSTORAGE_UNLIMITED;
+    user.usri3_primary_group_id = DOMAIN_GROUP_RID_USERS;
+
+    user.usri3_password_expired = TRUE;
+
+    if (DialogBoxParam(hApplet,
+                       MAKEINTRESOURCE(IDD_USER_NEW),
+                       hwndDlg,
+                       NewUserDlgProc,
+                       (LPARAM)&user) == IDOK)
+    {
+#if 0
+        status = NetUserAdd(NULL,
+                            3,
+                            (LPBYTE)&user,
+                            NULL);
+#else
+        status = NERR_Success;
+#endif
+        if (status != NERR_Success)
+        {
+            TCHAR szText[256];
+            wsprintf(szText, TEXT("Error: %u"), status);
+            MessageBox(NULL, szText, TEXT("NetUserAdd"), MB_ICONERROR | MB_OK);
+            return;
+        }
+
+        hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
+
+        ZeroMemory(&lvi, sizeof(lvi));
+        lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
+        lvi.pszText = user.usri3_name;
+        lvi.state = 0;
+        lvi.iImage = (user.usri3_flags & UF_ACCOUNTDISABLE) ? 1 : 0;
+        iItem = ListView_InsertItem(hwndLV, &lvi);
+
+        ListView_SetItemText(hwndLV, iItem, 1,
+                             user.usri3_full_name);
+
+        ListView_SetItemText(hwndLV, iItem, 2,
+                             user.usri3_comment);
+    }
+
+    if (user.usri3_name)
+        HeapFree(GetProcessHeap, 0, user.usri3_name);
+
+    if (user.usri3_full_name)
+        HeapFree(GetProcessHeap, 0, user.usri3_full_name);
+
+    if (user.usri3_comment)
+        HeapFree(GetProcessHeap, 0, user.usri3_comment);
+
+    if (user.usri3_password)
+        HeapFree(GetProcessHeap, 0, user.usri3_password);
+}
+
+
+static VOID
+UserRename(HWND hwndDlg)
+{
+    HWND hwndLV;
+    INT nItem;
+
+    hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
+    if (hwndLV == NULL)
+        return;
+
+    nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
+    if (nItem != -1)
+    {
+        (void)ListView_EditLabel(hwndLV, nItem);
+    }
+}
+
+
+static BOOL
+UserDelete(HWND hwndDlg)
+{
+    TCHAR szUserName[UNLEN];
+    TCHAR szText[256];
+    INT nItem;
+    HWND hwndLV;
+    NET_API_STATUS status;
+
+    hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
+    nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
+    if (nItem == -1)
+        return FALSE;
+
+    /* Get the new user name */
+    ListView_GetItemText(hwndLV,
+                         nItem, 0,
+                         szUserName,
+                         UNLEN);
+
+    /* Display a warning message because the delete operation cannot be reverted */
+    wsprintf(szText, TEXT("Dou you really want to delete the user \"%s\"?"), szUserName);
+    if (MessageBox(NULL, szText, TEXT("User Accounts"), MB_ICONWARNING | MB_YESNO) == IDNO)
+        return FALSE;
+
+    /* Delete the user */
+#if 0
+    status = NetUserDel(NULL, szUserName);
+#else
+    status = NERR_Success;
+#endif
+    if (status != NERR_Success)
+    {
+        TCHAR szText[256];
+        wsprintf(szText, TEXT("Error: %u"), status);
+        MessageBox(NULL, szText, TEXT("NetUserDel"), MB_ICONERROR | MB_OK);
+        return FALSE;
+    }
+
+    /* Delete the user from the list */
+    (void)ListView_DeleteItem(hwndLV, nItem);
+
+    return TRUE;
+}
+
+
+static VOID
+SetUsersListColumns(HWND hwndListView)
+{
+    LV_COLUMN column;
+    RECT rect;
+    TCHAR szStr[32];
+
+    GetClientRect(hwndListView, &rect);
+
+    memset(&column, 0x00, sizeof(column));
+    column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
+    column.fmt=LVCFMT_LEFT;
+    column.cx = (INT)((rect.right - rect.left) * 0.25);
+    column.iSubItem = 0;
+    LoadString(hApplet, IDS_NAME, szStr, sizeof(szStr) / sizeof(szStr[0]));
+    column.pszText = szStr;
+    (void)ListView_InsertColumn(hwndListView, 0, &column);
+
+    column.cx = (INT)((rect.right - rect.left) * 0.50);
+    column.iSubItem = 1;
+    LoadString(hApplet, IDS_FULLNAME, szStr, sizeof(szStr) / sizeof(szStr[0]));
+    column.pszText = szStr;
+    (void)ListView_InsertColumn(hwndListView, 1, &column);
+
+    column.cx = (INT)((rect.right - rect.left) * 0.25);
+    column.iSubItem = 2;
+    LoadString(hApplet, IDS_DESCRIPTION, szStr, sizeof(szStr) / sizeof(szStr[0]));
+    column.pszText = szStr;
+    (void)ListView_InsertColumn(hwndListView, 2, &column);
+}
+
+
+static VOID
+UpdateUsersList(HWND hwndListView)
+{
+    NET_API_STATUS netStatus;
+    PUSER_INFO_20 pBuffer;
+    DWORD entriesread;
+    DWORD totalentries;
+    DWORD resume_handle = 0;
+    DWORD i;
+    LV_ITEM lvi;
+    INT iItem;
+
+
+    for (;;)
+    {
+        netStatus = NetUserEnum(NULL, 20, FILTER_NORMAL_ACCOUNT,
+                                (LPBYTE*)&pBuffer,
+                                1024, &entriesread,
+                                &totalentries, &resume_handle);
+        if (netStatus != NERR_Success && netStatus != ERROR_MORE_DATA)
+            break;
+
+        for (i = 0; i < entriesread; i++)
+        {
+           memset(&lvi, 0x00, sizeof(lvi));
+           lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
+           lvi.pszText = pBuffer[i].usri20_name;
+           lvi.state = 0;
+           lvi.iImage = (pBuffer[i].usri20_flags & UF_ACCOUNTDISABLE) ? 1 : 0;
+           iItem = ListView_InsertItem(hwndListView, &lvi);
+
+           ListView_SetItemText(hwndListView, iItem, 1,
+                                pBuffer[i].usri20_full_name);
+
+           ListView_SetItemText(hwndListView, iItem, 2,
+                                pBuffer[i].usri20_comment);
+        }
+
+        NetApiBufferFree(&pBuffer);
+
+        /* No more data left */
+        if (netStatus != ERROR_MORE_DATA)
+            break;
+    }
+
+}
+
+
+static VOID
+OnInitDialog(HWND hwndDlg)
+{
+    HWND hwndListView;
+    HIMAGELIST hImgList;
+    HICON hIcon;
+
+    /* Create the image list */
+    hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 5, 5);
+    hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_USER), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+    ImageList_AddIcon(hImgList, hIcon);
+    hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_LOCKED_USER), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+    ImageList_AddIcon(hImgList, hIcon);
+    DestroyIcon(hIcon);
+
+    hwndListView = GetDlgItem(hwndDlg, IDC_USERS_LIST);
+
+    (VOID)ListView_SetImageList(hwndListView, hImgList, LVSIL_SMALL);
+
+    (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT);
+
+    SetUsersListColumns(hwndListView);
+
+    UpdateUsersList(hwndListView);
+}
+
+
+static BOOL
+OnBeginLabelEdit(LPNMLVDISPINFO pnmv)
+{
+    HWND hwndEdit;
+
+    hwndEdit = ListView_GetEditControl(pnmv->hdr.hwndFrom);
+    if (hwndEdit == NULL)
+        return TRUE;
+
+    SendMessage(hwndEdit, EM_SETLIMITTEXT, 20, 0);
+
+    return FALSE;
+}
+
+
+static BOOL
+OnEndLabelEdit(LPNMLVDISPINFO pnmv)
+{
+    TCHAR szOldUserName[UNLEN];
+    TCHAR szNewUserName[UNLEN];
+    USER_INFO_0 useri0;
+    NET_API_STATUS status;
+
+    /* Leave, if there is no valid listview item */
+    if (pnmv->item.iItem == -1)
+        return FALSE;
+
+    /* Get the new user name */
+    ListView_GetItemText(pnmv->hdr.hwndFrom,
+                         pnmv->item.iItem, 0,
+                         szOldUserName,
+                         UNLEN);
+
+    /* Leave, if the user canceled the edit action */
+    if (pnmv->item.pszText == NULL)
+        return FALSE;
+
+    /* Get the new user name */
+    lstrcpy(szNewUserName, pnmv->item.pszText);
+
+    /* Leave, if the user name was not changed */
+    if (lstrcmp(szOldUserName, szNewUserName) == 0)
+        return FALSE;
+
+    /* Check the user name for illegal characters */
+    if (!CheckAccountName(NULL, 0, szNewUserName))
+        return FALSE;
+
+    /* Change the user name */
+    useri0.usri0_name = szNewUserName;
+
+#if 0
+    status = NetUserSetInfo(NULL, szOldUserName, 0, (LPBYTE)&useri0, NULL);
+#else
+    status = NERR_Success;
+#endif
+    if (status != NERR_Success)
+    {
+        TCHAR szText[256];
+        wsprintf(szText, TEXT("Error: %u"), status);
+        MessageBox(NULL, szText, TEXT("NetUserSetInfo"), MB_ICONERROR | MB_OK);
+        return FALSE;
+    }
+
+    /* Update the listview item */
+    ListView_SetItemText(pnmv->hdr.hwndFrom,
+                         pnmv->item.iItem, 0,
+                         szNewUserName);
+
+    return TRUE;
+}
+
+
+static BOOL
+OnNotify(HWND hwndDlg, PUSER_DATA pUserData, NMHDR *phdr)
+{
+    LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
+
+    switch (phdr->idFrom)
+    {
+        case IDC_USERS_LIST:
+            switch(phdr->code)
+            {
+                case NM_CLICK:
+                    pUserData->iCurrentItem = lpnmlv->iItem;
+                    break;
+
+                case NM_DBLCLK:
+                    if (lpnmlv->iItem != -1)
+                    {
+                        UINT uItem;
+
+                        uItem =  GetMenuDefaultItem(GetSubMenu(pUserData->hPopupMenu, 1),
+                                                    FALSE, 0);
+                        if (uItem != (UINT)-1)
+                            SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(uItem, 0), 0);
+                    }
+                    break;
+
+                case NM_RCLICK:
+                    ClientToScreen(GetDlgItem(hwndDlg, IDC_USERS_LIST), &lpnmlv->ptAction);
+                    TrackPopupMenu(GetSubMenu(pUserData->hPopupMenu, (lpnmlv->iItem == -1) ? 0 : 1),
+                                   TPM_LEFTALIGN, lpnmlv->ptAction.x, lpnmlv->ptAction.y, 0, hwndDlg, NULL);
+                    break;
+
+                case LVN_BEGINLABELEDIT:
+                    return OnBeginLabelEdit((LPNMLVDISPINFO)phdr);
+
+                case LVN_ENDLABELEDIT:
+                    return OnEndLabelEdit((LPNMLVDISPINFO)phdr);
+            }
+            break;
+    }
+
+    return FALSE;
+}
+
+
+INT_PTR CALLBACK
+UsersPageProc(HWND hwndDlg,
+              UINT uMsg,
+              WPARAM wParam,
+              LPARAM lParam)
+{
+    PUSER_DATA pUserData;
+
+    UNREFERENCED_PARAMETER(wParam);
+
+    pUserData = (PUSER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
+
+    switch (uMsg)
+    {
+        case WM_INITDIALOG:
+            pUserData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(USER_DATA));
+            SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pUserData);
+
+            pUserData->hPopupMenu = LoadMenu(hApplet, MAKEINTRESOURCE(IDM_POPUP_USER));
+
+            OnInitDialog(hwndDlg);
+            SetMenuDefaultItem(GetSubMenu(pUserData->hPopupMenu, 1),
+                               IDM_USER_PROPERTIES,
+                               FALSE);
+            break;
+
+        case WM_COMMAND:
+            switch (LOWORD(wParam))
+            {
+                case IDM_USER_CHANGE_PASSWORD:
+                    DialogBoxParam(hApplet,
+                                   MAKEINTRESOURCE(IDD_CHANGE_PASSWORD),
+                                   hwndDlg,
+                                   ChangePasswordDlgProc,
+                                   (LPARAM)NULL);
+                    break;
+
+                case IDM_USER_RENAME:
+                    UserRename(hwndDlg);
+                    break;
+
+                case IDM_USER_NEW:
+                    UserNew(hwndDlg);
+                    break;
+
+                case IDM_USER_DELETE:
+                    UserDelete(hwndDlg);
+                    break;
+
+                case IDM_USER_PROPERTIES:
+                    UserProperties(hwndDlg);
+                    break;
+            }
+            break;
+
+        case WM_NOTIFY:
+            return OnNotify(hwndDlg, pUserData, (NMHDR *)lParam);
+
+        case WM_DESTROY:
+            DestroyMenu(pUserData->hPopupMenu);
+            HeapFree(GetProcessHeap(), 0, pUserData);
+            break;
+    }
+
+    return FALSE;
+}
index 142223b..91c39d5 100644 (file)
@@ -1,39 +1,43 @@
-#ifndef __CPL_DESK_H__\r
-#define __CPL_DESK_H__\r
-\r
-#include <windows.h>\r
-#include <commctrl.h>\r
-#include <commdlg.h>\r
-#include <cpl.h>\r
-#include <tchar.h>\r
-#include <setupapi.h>\r
-#include <lmaccess.h>\r
-#include <lmapibuf.h>\r
-#include <lmerr.h>\r
-#include <stdio.h>\r
-\r
-#include "resource.h"\r
-\r
-typedef struct _APPLET\r
-{\r
-    int idIcon;\r
-    int idName;\r
-    int idDescription;\r
-    APPLET_PROC AppletProc;\r
-} APPLET, *PAPPLET;\r
-\r
-extern HINSTANCE hApplet;\r
-\r
-\r
-INT_PTR CALLBACK UsersPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);\r
-INT_PTR CALLBACK GroupsPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);\r
-INT_PTR CALLBACK ExtraPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);\r
-\r
-/* misc.c */\r
-BOOL\r
-CheckAccountName(HWND hwndDlg,\r
-                 INT nIdDlgItem,\r
-                 LPTSTR lpAccountName);\r
-\r
-#endif /* __CPL_DESK_H__ */\r
-\r
+#ifndef __CPL_DESK_H__
+#define __CPL_DESK_H__
+
+#include <windows.h>
+#include <commctrl.h>
+#include <commdlg.h>
+#include <cpl.h>
+#include <tchar.h>
+#include <setupapi.h>
+#include <lmaccess.h>
+#include <lmapibuf.h>
+#include <lmerr.h>
+#include <stdio.h>
+
+#include "resource.h"
+
+typedef struct _APPLET
+{
+    int idIcon;
+    int idName;
+    int idDescription;
+    APPLET_PROC AppletProc;
+} APPLET, *PAPPLET;
+
+extern HINSTANCE hApplet;
+
+
+INT_PTR CALLBACK UsersPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK GroupsPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK ExtraPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+/* misc.c */
+BOOL
+CheckAccountName(HWND hwndDlg,
+                 INT nIdDlgItem,
+                 LPTSTR lpAccountName);
+
+/* userprops.c */
+VOID
+UserProperties(HWND hwndDlg);
+
+#endif /* __CPL_DESK_H__ */
+
index 8e0ca9e..1f0ce25 100644 (file)
@@ -1,22 +1,23 @@
-<?xml version="1.0"?>\r
-<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">\r
-<module name="usrmgr" type="win32dll" extension=".cpl" baseaddress="${BASEADDRESS_USRMGR}" installbase="system32" installname="usrmgr.cpl" unicode="yes">\r
-       <importlibrary definition="usrmgr.def" />\r
-       <include base="usrmgr">.</include>\r
-       <define name="_WIN32_IE">0x600</define>\r
-       <define name="_WIN32_WINNT">0x501</define>\r
-       <define name="WINVER">0x609</define>\r
-       <library>kernel32</library>\r
-       <library>user32</library>\r
-       <library>gdi32</library>\r
-       <library>comctl32</library>\r
-       <library>ntdll</library>\r
-       <library>netapi32</library>\r
-       <library>msvcrt</library>\r
-       <file>extra.c</file>\r
-       <file>groups.c</file>\r
-       <file>misc.c</file>\r
-       <file>users.c</file>\r
-       <file>usrmgr.c</file>\r
-       <file>usrmgr.rc</file>\r
-</module>\r
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<module name="usrmgr" type="win32dll" extension=".cpl" baseaddress="${BASEADDRESS_USRMGR}" installbase="system32" installname="usrmgr.cpl" unicode="yes">
+       <importlibrary definition="usrmgr.def" />
+       <include base="usrmgr">.</include>
+       <define name="_WIN32_IE">0x600</define>
+       <define name="_WIN32_WINNT">0x501</define>
+       <define name="WINVER">0x609</define>
+       <library>kernel32</library>
+       <library>user32</library>
+       <library>gdi32</library>
+       <library>comctl32</library>
+       <library>ntdll</library>
+       <library>netapi32</library>
+       <library>msvcrt</library>
+       <file>extra.c</file>
+       <file>groups.c</file>
+       <file>misc.c</file>
+       <file>userprops.c</file>
+       <file>users.c</file>
+       <file>usrmgr.c</file>
+       <file>usrmgr.rc</file>
+</module>