- Merge from trunk up to r45543
[reactos.git] / dll / cpl / usrmgr / userprops.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS User Manager Control Panel
4 * FILE: dll/cpl/usrmgr/userprops.c
5 * PURPOSE: User property sheet
6 *
7 * PROGRAMMERS: Eric Kohl
8 */
9
10 #include "usrmgr.h"
11
12 typedef struct _GENERAL_USER_DATA
13 {
14 DWORD dwFlags;
15 DWORD dwPasswordExpired;
16 TCHAR szUserName[1];
17 } GENERAL_USER_DATA, *PGENERAL_USER_DATA;
18
19 #define VALID_GENERAL_FLAGS (UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD | UF_ACCOUNTDISABLE | UF_LOCKOUT)
20
21 typedef struct _PROFILE_USER_DATA
22 {
23 TCHAR szUserName[1];
24 } PROFILE_USER_DATA, *PPROFILE_USER_DATA;
25
26 typedef struct _MEMBERSHIP_USER_DATA
27 {
28 PLOCALGROUP_USERS_INFO_0 pGroupData;
29 DWORD dwGroupCount;
30 TCHAR szUserName[1];
31 } MEMBERSHIP_USER_DATA, *PMEMBERSHIP_USER_DATA;
32
33
34 static VOID
35 GetUserProfileData(HWND hwndDlg,
36 PPROFILE_USER_DATA pUserData)
37 {
38 PUSER_INFO_3 userInfo = NULL;
39 NET_API_STATUS status;
40 BOOL bLocal;
41 TCHAR szDrive[8];
42 INT i;
43 INT nSel;
44
45 status = NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&userInfo);
46 if (status != NERR_Success)
47 return;
48
49 SetDlgItemText(hwndDlg, IDC_USER_PROFILE_PATH, userInfo->usri3_profile);
50 SetDlgItemText(hwndDlg, IDC_USER_PROFILE_SCRIPT, userInfo->usri3_script_path);
51
52
53 bLocal = (userInfo->usri3_home_dir_drive == NULL) ||
54 (_tcslen(userInfo->usri3_home_dir_drive) == 0);
55 CheckRadioButton(hwndDlg, IDC_USER_PROFILE_LOCAL, IDC_USER_PROFILE_REMOTE,
56 bLocal ? IDC_USER_PROFILE_LOCAL : IDC_USER_PROFILE_REMOTE);
57
58 for (i = 0; i < 26; i++)
59 {
60 wsprintf(szDrive, _T("%c:"), (TCHAR)('A' + i));
61 nSel = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE),
62 CB_INSERTSTRING, -1, (LPARAM)szDrive);
63 }
64
65 if (bLocal)
66 {
67 SetDlgItemText(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH, userInfo->usri3_home_dir);
68 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), FALSE);
69 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH), FALSE);
70 }
71 else
72 {
73 SetDlgItemText(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH, userInfo->usri3_home_dir);
74 nSel = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE),
75 CB_FINDSTRINGEXACT, -1, (LPARAM)userInfo->usri3_home_dir_drive);
76 }
77
78 SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE),
79 CB_SETCURSEL, nSel, 0);
80
81 NetApiBufferFree(userInfo);
82 }
83
84
85 static BOOL
86 SetUserProfileData(HWND hwndDlg,
87 PPROFILE_USER_DATA pUserData)
88 {
89 PUSER_INFO_3 pUserInfo = NULL;
90 LPTSTR pszProfilePath = NULL;
91 LPTSTR pszScriptPath = NULL;
92 LPTSTR pszHomeDir = NULL;
93 LPTSTR pszHomeDrive = NULL;
94 NET_API_STATUS status;
95 #if 0
96 DWORD dwIndex;
97 #endif
98 INT nLength;
99 INT nIndex;
100
101 NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&pUserInfo);
102
103 /* Get the profile path */
104 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_PROFILE_PATH));
105 if (nLength == 0)
106 {
107 pUserInfo->usri3_profile = NULL;
108 }
109 else
110 {
111 pszProfilePath = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
112 GetDlgItemText(hwndDlg, IDC_USER_PROFILE_PATH, pszProfilePath, nLength + 1);
113 pUserInfo->usri3_profile = pszProfilePath;
114 }
115
116 /* Get the script path */
117 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_PROFILE_SCRIPT));
118 if (nLength == 0)
119 {
120 pUserInfo->usri3_script_path = NULL;
121 }
122 else
123 {
124 pszScriptPath = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
125 GetDlgItemText(hwndDlg, IDC_USER_PROFILE_SCRIPT, pszScriptPath, nLength + 1);
126 pUserInfo->usri3_script_path = pszScriptPath;
127 }
128
129 if (IsDlgButtonChecked(hwndDlg, IDC_USER_PROFILE_LOCAL) == BST_CHECKED)
130 {
131 /* Local home directory */
132 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH));
133 if (nLength == 0)
134 {
135 pUserInfo->usri3_home_dir = NULL;
136 }
137 else
138 {
139 pszHomeDir = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
140 GetDlgItemText(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH, pszHomeDir, nLength + 1);
141 pUserInfo->usri3_home_dir = pszHomeDir;
142 }
143 }
144 else
145 {
146 /* Remote home directory */
147 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH));
148 if (nLength == 0)
149 {
150 pUserInfo->usri3_home_dir = NULL;
151 }
152 else
153 {
154 pszHomeDir = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
155 GetDlgItemText(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH, pszHomeDir, nLength + 1);
156 pUserInfo->usri3_home_dir = pszHomeDir;
157 }
158
159 nIndex = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), CB_GETCURSEL, 0, 0);
160 if (nIndex != CB_ERR)
161 {
162 nLength = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), CB_GETLBTEXTLEN, nIndex, 0);
163 pszHomeDrive = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
164 SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), CB_GETLBTEXT, nIndex, (LPARAM)pszHomeDrive);
165 pUserInfo->usri3_home_dir_drive = pszHomeDrive;
166 }
167 }
168
169 #if 0
170 status = NetUserSetInfo(NULL, pUserData->szUserName, 3, (LPBYTE)pUserInfo, &dwIndex);
171 if (status != NERR_Success)
172 {
173 DebugPrintf(_T("Status: %lu Index: %lu"), status, dwIndex);
174 }
175 #else
176 status = NERR_Success;
177 #endif
178
179 if (pszProfilePath)
180 HeapFree(GetProcessHeap(), 0, pszProfilePath);
181
182 if (pszScriptPath)
183 HeapFree(GetProcessHeap(), 0, pszScriptPath);
184
185 if (pszHomeDir)
186 HeapFree(GetProcessHeap(), 0, pszHomeDir);
187
188 if (pszHomeDrive)
189 HeapFree(GetProcessHeap(), 0, pszHomeDrive);
190
191 NetApiBufferFree(pUserInfo);
192
193 return (status == NERR_Success);
194 }
195
196
197 INT_PTR CALLBACK
198 UserProfilePageProc(HWND hwndDlg,
199 UINT uMsg,
200 WPARAM wParam,
201 LPARAM lParam)
202 {
203 PPROFILE_USER_DATA pUserData;
204
205 UNREFERENCED_PARAMETER(lParam);
206 UNREFERENCED_PARAMETER(wParam);
207 UNREFERENCED_PARAMETER(hwndDlg);
208
209 pUserData= (PPROFILE_USER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
210
211 switch (uMsg)
212 {
213 case WM_INITDIALOG:
214 pUserData = (PPROFILE_USER_DATA)HeapAlloc(GetProcessHeap(),
215 HEAP_ZERO_MEMORY,
216 sizeof(PROFILE_USER_DATA) +
217 lstrlen((LPTSTR)((PROPSHEETPAGE *)lParam)->lParam) * sizeof(TCHAR));
218 lstrcpy(pUserData->szUserName, (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
219
220 SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pUserData);
221
222 GetUserProfileData(hwndDlg,
223 pUserData);
224 break;
225
226 case WM_COMMAND:
227 switch (LOWORD(wParam))
228 {
229 case IDC_USER_PROFILE_PATH:
230 case IDC_USER_PROFILE_SCRIPT:
231 if (HIWORD(wParam) == EN_CHANGE)
232 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
233 break;
234
235 case IDC_USER_PROFILE_LOCAL:
236 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH), TRUE);
237 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), FALSE);
238 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH), FALSE);
239 break;
240
241 case IDC_USER_PROFILE_REMOTE:
242 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH), FALSE);
243 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), TRUE);
244 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH), TRUE);
245 break;
246 }
247 break;
248
249 case WM_DESTROY:
250 HeapFree(GetProcessHeap(), 0, pUserData);
251 break;
252
253 case WM_NOTIFY:
254 if (((LPPSHNOTIFY)lParam)->hdr.code == PSN_APPLY)
255 {
256 SetUserProfileData(hwndDlg, pUserData);
257 return TRUE;
258 }
259 break;
260 }
261
262 return FALSE;
263 }
264
265
266 static VOID
267 GetUserMembershipData(HWND hwndDlg, PMEMBERSHIP_USER_DATA pUserData)
268 {
269 NET_API_STATUS status;
270 DWORD dwTotal;
271 DWORD i;
272 HIMAGELIST hImgList;
273 HICON hIcon;
274 LV_ITEM lvi;
275 HWND hwndLV;
276 LV_COLUMN column;
277 RECT rect;
278
279
280 hwndLV = GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_LIST);
281
282 /* Create the image list */
283 hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 5, 5);
284 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_GROUP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
285 ImageList_AddIcon(hImgList, hIcon);
286 DestroyIcon(hIcon);
287 (void)ListView_SetImageList(hwndLV, hImgList, LVSIL_SMALL);
288
289 /* Set the list column */
290 GetClientRect(hwndLV, &rect);
291
292 memset(&column, 0x00, sizeof(column));
293 column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
294 column.fmt = LVCFMT_LEFT;
295 column.cx = (INT)(rect.right - rect.left);
296 column.iSubItem = 0;
297 (void)ListView_InsertColumn(hwndLV, 0, &column);
298
299
300 status = NetUserGetLocalGroups(NULL, pUserData->szUserName, 0, 0,
301 (LPBYTE*)&pUserData->pGroupData,
302 MAX_PREFERRED_LENGTH,
303 &pUserData->dwGroupCount,
304 &dwTotal);
305 if (status != NERR_Success)
306 return;
307
308 for (i = 0; i < pUserData->dwGroupCount; i++)
309 {
310 ZeroMemory(&lvi, sizeof(lvi));
311 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
312 lvi.pszText = pUserData->pGroupData[i].lgrui0_name;
313 lvi.state = 0;
314 lvi.iImage = 0;
315
316 (void)ListView_InsertItem(hwndLV, &lvi);
317 }
318 }
319
320
321 static VOID
322 RemoveGroupFromUser(HWND hwndDlg,
323 PMEMBERSHIP_USER_DATA pUserData)
324 {
325 TCHAR szGroupName[UNLEN];
326 TCHAR szText[256];
327 LOCALGROUP_MEMBERS_INFO_3 memberInfo;
328 HWND hwndLV;
329 INT nItem;
330 NET_API_STATUS status;
331
332 hwndLV = GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_LIST);
333 nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
334 if (nItem == -1)
335 return;
336
337 /* Get the new user name */
338 ListView_GetItemText(hwndLV,
339 nItem, 0,
340 szGroupName,
341 UNLEN);
342
343 /* Display a warning message because the remove operation cannot be reverted */
344 wsprintf(szText, TEXT("Do you really want to remove the user \"%s\" from the group \"%s\"?"),
345 pUserData->szUserName, szGroupName);
346 if (MessageBox(NULL, szText, TEXT("User Accounts"), MB_ICONWARNING | MB_YESNO) == IDNO)
347 return;
348
349 memberInfo.lgrmi3_domainandname = pUserData->szUserName;
350
351 status = NetLocalGroupDelMembers(NULL, szGroupName,
352 3, (LPBYTE)&memberInfo, 1);
353 if (status != NERR_Success)
354 {
355 TCHAR szText[256];
356 wsprintf(szText, TEXT("Error: %u"), status);
357 MessageBox(NULL, szText, TEXT("NetLocalGroupDelMembers"), MB_ICONERROR | MB_OK);
358 return;
359 }
360
361 (void)ListView_DeleteItem(hwndLV, nItem);
362
363 if (ListView_GetItemCount(hwndLV) == 0)
364 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_REMOVE), FALSE);
365 }
366
367
368 static VOID
369 InitUserGroupsList(HWND hwndDlg)
370 {
371 HWND hwndLV;
372 LV_COLUMN column;
373 RECT rect;
374 TCHAR szStr[32];
375
376 NET_API_STATUS netStatus;
377 PLOCALGROUP_INFO_1 pBuffer;
378 DWORD entriesread;
379 DWORD totalentries;
380 DWORD_PTR resume_handle = 0;
381 DWORD i;
382 LV_ITEM lvi;
383 INT iItem;
384
385 HIMAGELIST hImgList;
386 HICON hIcon;
387
388 hwndLV = GetDlgItem(hwndDlg, IDC_USER_ADD_MEMBERSHIP_LIST);
389 GetClientRect(hwndLV, &rect);
390
391 hImgList = ImageList_Create(16,16,ILC_COLOR8 | ILC_MASK,5,5);
392 hIcon = LoadImage(hApplet,MAKEINTRESOURCE(IDI_GROUP),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
393 ImageList_AddIcon(hImgList,hIcon);
394 DestroyIcon(hIcon);
395
396 (void)ListView_SetImageList(hwndLV, hImgList, LVSIL_SMALL);
397 (void)ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
398
399 memset(&column, 0x00, sizeof(column));
400 column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
401 column.fmt = LVCFMT_LEFT;
402 column.cx = (INT)((rect.right - rect.left) * 0.40);
403 column.iSubItem = 0;
404 LoadString(hApplet, IDS_NAME, szStr, sizeof(szStr) / sizeof(szStr[0]));
405 column.pszText = szStr;
406 (void)ListView_InsertColumn(hwndLV, 0, &column);
407
408 column.cx = (INT)((rect.right - rect.left) * 0.60);
409 column.iSubItem = 1;
410 LoadString(hApplet, IDS_DESCRIPTION, szStr, sizeof(szStr) / sizeof(szStr[0]));
411 column.pszText = szStr;
412 (void)ListView_InsertColumn(hwndLV, 1, &column);
413
414 for (;;)
415 {
416 netStatus = NetLocalGroupEnum(NULL, 1, (LPBYTE*)&pBuffer,
417 1024, &entriesread,
418 &totalentries, &resume_handle);
419 if (netStatus != NERR_Success && netStatus != ERROR_MORE_DATA)
420 break;
421
422 for (i = 0; i < entriesread; i++)
423 {
424 memset(&lvi, 0x00, sizeof(lvi));
425 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
426 lvi.pszText = pBuffer[i].lgrpi1_name;
427 lvi.state = 0;
428 lvi.iImage = 0;
429 iItem = ListView_InsertItem(hwndLV, &lvi);
430
431 ListView_SetItemText(hwndLV, iItem, 1,
432 pBuffer[i].lgrpi1_comment);
433 }
434
435 NetApiBufferFree(&pBuffer);
436
437 /* No more data left */
438 if (netStatus != ERROR_MORE_DATA)
439 break;
440 }
441 }
442
443
444 static BOOL
445 AddSelectedGroupsToUser(HWND hwndDlg,
446 PMEMBERSHIP_USER_DATA pUserData)
447 {
448 HWND hwndLV;
449 INT nItem;
450 TCHAR szGroupName[UNLEN];
451 BOOL bResult = FALSE;
452 BOOL bFound;
453 DWORD i;
454 LOCALGROUP_MEMBERS_INFO_3 memberInfo;
455 NET_API_STATUS status;
456
457 hwndLV = GetDlgItem(hwndDlg, IDC_USER_ADD_MEMBERSHIP_LIST);
458
459 if (ListView_GetSelectedCount(hwndLV) > 0)
460 {
461 nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
462 while (nItem != -1)
463 {
464 /* Get the new user name */
465 ListView_GetItemText(hwndLV,
466 nItem, 0,
467 szGroupName,
468 UNLEN);
469
470 bFound = FALSE;
471 for (i = 0; i < pUserData->dwGroupCount; i++)
472 {
473 if (_tcscmp(pUserData->pGroupData[i].lgrui0_name, szGroupName) == 0)
474 bFound = TRUE;
475 }
476
477 if (!bFound)
478 {
479 memberInfo.lgrmi3_domainandname = pUserData->szUserName;
480
481 status = NetLocalGroupAddMembers(NULL, szGroupName, 3,
482 (LPBYTE)&memberInfo, 1);
483 if (status == NERR_Success)
484 {
485 DebugPrintf(_TEXT("Selected group: %s"), szGroupName);
486 bResult = TRUE;
487 }
488 else
489 {
490 TCHAR szText[256];
491 wsprintf(szText, TEXT("Error: %u"), status);
492 MessageBox(NULL, szText, TEXT("NetLocalGroupAddMembers"), MB_ICONERROR | MB_OK);
493 }
494 }
495
496 nItem = ListView_GetNextItem(hwndLV, nItem, LVNI_SELECTED);
497 }
498 }
499
500 return bResult;
501 }
502
503
504 INT_PTR CALLBACK
505 AddGroupToUserDlgProc(HWND hwndDlg,
506 UINT uMsg,
507 WPARAM wParam,
508 LPARAM lParam)
509 {
510 PMEMBERSHIP_USER_DATA pUserData;
511
512 UNREFERENCED_PARAMETER(wParam);
513
514 pUserData= (PMEMBERSHIP_USER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
515
516 switch (uMsg)
517 {
518 case WM_INITDIALOG:
519 pUserData= (PMEMBERSHIP_USER_DATA)lParam;
520 SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pUserData);
521 InitUserGroupsList(hwndDlg);
522 break;
523
524 case WM_COMMAND:
525 switch (LOWORD(wParam))
526 {
527 case IDOK:
528 if (AddSelectedGroupsToUser(hwndDlg, pUserData))
529 EndDialog(hwndDlg, IDOK);
530 else
531 EndDialog(hwndDlg, IDCANCEL);
532 break;
533
534 case IDCANCEL:
535 EndDialog(hwndDlg, IDCANCEL);
536 break;
537 }
538 break;
539
540 default:
541 return FALSE;
542 }
543
544 return TRUE;
545 }
546
547
548 static VOID
549 AddGroupToUser(HWND hwndDlg,
550 PMEMBERSHIP_USER_DATA pUserData)
551 {
552 HWND hwndLV;
553 NET_API_STATUS status;
554 DWORD i;
555 DWORD dwTotal;
556 LV_ITEM lvi;
557
558 if (DialogBoxParam(hApplet,
559 MAKEINTRESOURCE(IDD_USER_ADD_MEMBERSHIP),
560 hwndDlg,
561 AddGroupToUserDlgProc,
562 (LPARAM)pUserData) == IDOK)
563 {
564 // TODO: Update Membership list!
565 hwndLV = GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_LIST);
566
567 if (pUserData->pGroupData)
568 NetApiBufferFree(pUserData->pGroupData);
569
570 (void)ListView_DeleteAllItems(hwndLV);
571
572 status = NetUserGetLocalGroups(NULL, pUserData->szUserName, 0, 0,
573 (LPBYTE*)&pUserData->pGroupData,
574 MAX_PREFERRED_LENGTH,
575 &pUserData->dwGroupCount,
576 &dwTotal);
577 if (status != NERR_Success)
578 return;
579
580 for (i = 0; i < pUserData->dwGroupCount; i++)
581 {
582 ZeroMemory(&lvi, sizeof(lvi));
583 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
584 lvi.pszText = pUserData->pGroupData[i].lgrui0_name;
585 lvi.state = 0;
586 lvi.iImage = 0;
587
588 (void)ListView_InsertItem(hwndLV, &lvi);
589 }
590 }
591 }
592
593
594 static BOOL
595 OnNotify(HWND hwndDlg,
596 PMEMBERSHIP_USER_DATA pUserData,
597 LPARAM lParam)
598 {
599 LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lParam;
600
601 switch (((LPNMHDR)lParam)->idFrom)
602 {
603 case IDC_USER_MEMBERSHIP_LIST:
604 switch (((LPNMHDR)lParam)->code)
605 {
606 case NM_CLICK:
607 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_REMOVE), (lpnmlv->iItem != -1));
608 break;
609
610 case LVN_KEYDOWN:
611 if (((LPNMLVKEYDOWN)lParam)->wVKey == VK_DELETE)
612 {
613 RemoveGroupFromUser(hwndDlg, pUserData);
614 }
615 break;
616
617 }
618 break;
619 }
620
621 return FALSE;
622 }
623
624
625 INT_PTR CALLBACK
626 UserMembershipPageProc(HWND hwndDlg,
627 UINT uMsg,
628 WPARAM wParam,
629 LPARAM lParam)
630 {
631 PMEMBERSHIP_USER_DATA pUserData;
632
633 UNREFERENCED_PARAMETER(lParam);
634 UNREFERENCED_PARAMETER(wParam);
635 UNREFERENCED_PARAMETER(hwndDlg);
636
637 pUserData= (PMEMBERSHIP_USER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
638
639 switch (uMsg)
640 {
641 case WM_INITDIALOG:
642 pUserData = (PMEMBERSHIP_USER_DATA)HeapAlloc(GetProcessHeap(),
643 HEAP_ZERO_MEMORY,
644 sizeof(MEMBERSHIP_USER_DATA) +
645 lstrlen((LPTSTR)((PROPSHEETPAGE *)lParam)->lParam) * sizeof(TCHAR));
646 lstrcpy(pUserData->szUserName, (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
647
648 SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pUserData);
649
650 GetUserMembershipData(hwndDlg, pUserData);
651 break;
652
653 case WM_COMMAND:
654 switch (LOWORD(wParam))
655 {
656 case IDC_USER_MEMBERSHIP_ADD:
657 AddGroupToUser(hwndDlg, pUserData);
658 break;
659
660 case IDC_USER_MEMBERSHIP_REMOVE:
661 RemoveGroupFromUser(hwndDlg, pUserData);
662 break;
663 }
664 break;
665
666 case WM_NOTIFY:
667 if (((LPPSHNOTIFY)lParam)->hdr.code == PSN_APPLY)
668 {
669 return TRUE;
670 }
671 else
672 {
673 return OnNotify(hwndDlg, pUserData, lParam);
674 }
675 break;
676
677
678 case WM_DESTROY:
679 if (pUserData->pGroupData)
680 NetApiBufferFree(pUserData->pGroupData);
681
682 HeapFree(GetProcessHeap(), 0, pUserData);
683 break;
684 }
685
686 return FALSE;
687 }
688
689
690 static VOID
691 UpdateUserOptions(HWND hwndDlg,
692 PGENERAL_USER_DATA pUserData,
693 BOOL bInit)
694 {
695 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_CANNOT_CHANGE),
696 !pUserData->dwPasswordExpired);
697 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_NEVER_EXPIRES),
698 !pUserData->dwPasswordExpired);
699 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_FORCE_CHANGE),
700 (pUserData->dwFlags & (UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD)) == 0);
701
702 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_LOCKED),
703 (pUserData->dwFlags & UF_LOCKOUT) != 0);
704
705 if (bInit)
706 {
707 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_FORCE_CHANGE,
708 pUserData->dwPasswordExpired ? BST_CHECKED : BST_UNCHECKED);
709
710 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_CANNOT_CHANGE,
711 (pUserData->dwFlags & UF_PASSWD_CANT_CHANGE) ? BST_CHECKED : BST_UNCHECKED);
712
713 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_NEVER_EXPIRES,
714 (pUserData->dwFlags & UF_DONT_EXPIRE_PASSWD) ? BST_CHECKED : BST_UNCHECKED);
715
716 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_DISABLED,
717 (pUserData->dwFlags & UF_ACCOUNTDISABLE) ? BST_CHECKED : BST_UNCHECKED);
718
719 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_LOCKED,
720 (pUserData->dwFlags & UF_LOCKOUT) ? BST_CHECKED : BST_UNCHECKED);
721 }
722 }
723
724
725 static VOID
726 GetUserGeneralData(HWND hwndDlg,
727 PGENERAL_USER_DATA pUserData)
728 {
729 PUSER_INFO_3 pUserInfo = NULL;
730
731 SetDlgItemText(hwndDlg, IDC_USER_GENERAL_NAME, pUserData->szUserName);
732
733 NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&pUserInfo);
734
735 SetDlgItemText(hwndDlg, IDC_USER_GENERAL_FULL_NAME, pUserInfo->usri3_full_name);
736 SetDlgItemText(hwndDlg, IDC_USER_GENERAL_DESCRIPTION, pUserInfo->usri3_comment);
737
738 pUserData->dwFlags = pUserInfo->usri3_flags;
739 pUserData->dwPasswordExpired = pUserInfo->usri3_password_expired;
740
741 NetApiBufferFree(pUserInfo);
742
743 UpdateUserOptions(hwndDlg, pUserData, TRUE);
744 }
745
746
747 static BOOL
748 SetUserGeneralData(HWND hwndDlg,
749 PGENERAL_USER_DATA pUserData)
750 {
751 PUSER_INFO_3 pUserInfo = NULL;
752 LPTSTR pszFullName = NULL;
753 LPTSTR pszComment = NULL;
754 NET_API_STATUS status;
755 #if 0
756 DWORD dwIndex;
757 #endif
758 INT nLength;
759
760 NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&pUserInfo);
761
762 pUserInfo->usri3_flags =
763 (pUserData->dwFlags & VALID_GENERAL_FLAGS) |
764 (pUserInfo->usri3_flags & ~VALID_GENERAL_FLAGS);
765
766 pUserInfo->usri3_password_expired = pUserData->dwPasswordExpired;
767
768 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_GENERAL_FULL_NAME));
769 if (nLength == 0)
770 {
771 pUserInfo->usri3_full_name = NULL;
772 }
773 else
774 {
775 pszFullName = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
776 GetDlgItemText(hwndDlg, IDC_USER_GENERAL_FULL_NAME, pszFullName, nLength + 1);
777 pUserInfo->usri3_full_name = pszFullName;
778 }
779
780 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_GENERAL_DESCRIPTION));
781 if (nLength == 0)
782 {
783 pUserInfo->usri3_full_name = NULL;
784 }
785 else
786 {
787 pszComment = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
788 GetDlgItemText(hwndDlg, IDC_USER_GENERAL_DESCRIPTION, pszComment, nLength + 1);
789 pUserInfo->usri3_comment = pszComment;
790 }
791
792 #if 0
793 status = NetUserSetInfo(NULL, pUserData->szUserName, 3, (LPBYTE)pUserInfo, &dwIndex);
794 if (status != NERR_Success)
795 {
796 DebugPrintf(_T("Status: %lu Index: %lu"), status, dwIndex);
797 }
798 #else
799 status = NERR_Success;
800 #endif
801
802 if (pszFullName)
803 HeapFree(GetProcessHeap(), 0, pszFullName);
804
805 if (pszComment)
806 HeapFree(GetProcessHeap(), 0, pszComment);
807
808 NetApiBufferFree(pUserInfo);
809
810 return (status == NERR_Success);
811 }
812
813
814 INT_PTR CALLBACK
815 UserGeneralPageProc(HWND hwndDlg,
816 UINT uMsg,
817 WPARAM wParam,
818 LPARAM lParam)
819 {
820 PGENERAL_USER_DATA pUserData;
821
822 UNREFERENCED_PARAMETER(lParam);
823 UNREFERENCED_PARAMETER(wParam);
824 UNREFERENCED_PARAMETER(hwndDlg);
825
826 pUserData= (PGENERAL_USER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
827
828 switch (uMsg)
829 {
830 case WM_INITDIALOG:
831 pUserData = (PGENERAL_USER_DATA)HeapAlloc(GetProcessHeap(),
832 HEAP_ZERO_MEMORY,
833 sizeof(GENERAL_USER_DATA) +
834 lstrlen((LPTSTR)((PROPSHEETPAGE *)lParam)->lParam) * sizeof(TCHAR));
835 lstrcpy(pUserData->szUserName, (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
836
837 SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pUserData);
838
839 GetUserGeneralData(hwndDlg,
840 pUserData);
841 break;
842
843 case WM_COMMAND:
844 switch (LOWORD(wParam))
845 {
846 case IDC_USER_GENERAL_FULL_NAME:
847 case IDC_USER_GENERAL_DESCRIPTION:
848 if (HIWORD(wParam) == EN_CHANGE)
849 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
850 break;
851
852 case IDC_USER_GENERAL_FORCE_CHANGE:
853 pUserData->dwPasswordExpired = !pUserData->dwPasswordExpired;
854 UpdateUserOptions(hwndDlg, pUserData, FALSE);
855 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
856 break;
857
858 case IDC_USER_GENERAL_CANNOT_CHANGE:
859 pUserData->dwFlags ^= UF_PASSWD_CANT_CHANGE;
860 UpdateUserOptions(hwndDlg, pUserData, FALSE);
861 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
862 break;
863
864 case IDC_USER_GENERAL_NEVER_EXPIRES:
865 pUserData->dwFlags ^= UF_DONT_EXPIRE_PASSWD;
866 UpdateUserOptions(hwndDlg, pUserData, FALSE);
867 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
868 break;
869
870 case IDC_USER_GENERAL_DISABLED:
871 pUserData->dwFlags ^= UF_ACCOUNTDISABLE;
872 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
873 break;
874
875 case IDC_USER_GENERAL_LOCKED:
876 pUserData->dwFlags ^= UF_LOCKOUT;
877 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
878 break;
879 }
880 break;
881
882 case WM_NOTIFY:
883 if (((LPPSHNOTIFY)lParam)->hdr.code == PSN_APPLY)
884 {
885 SetUserGeneralData(hwndDlg, pUserData);
886 return TRUE;
887 }
888 break;
889
890 case WM_DESTROY:
891 HeapFree(GetProcessHeap(), 0, pUserData);
892 break;
893 }
894
895 return FALSE;
896 }
897
898
899 static VOID
900 InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc, LPTSTR pszUser)
901 {
902 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
903 psp->dwSize = sizeof(PROPSHEETPAGE);
904 psp->dwFlags = PSP_DEFAULT;
905 psp->hInstance = hApplet;
906 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
907 psp->pfnDlgProc = DlgProc;
908 psp->lParam = (LPARAM)pszUser;
909 }
910
911
912 BOOL
913 UserProperties(HWND hwndDlg)
914 {
915 PROPSHEETPAGE psp[3];
916 PROPSHEETHEADER psh;
917 TCHAR szUserName[UNLEN];
918 INT nItem;
919 HWND hwndLV;
920
921 hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
922 nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
923 if (nItem == -1)
924 return FALSE;
925
926 /* Get the new user name */
927 ListView_GetItemText(hwndLV,
928 nItem, 0,
929 szUserName,
930 UNLEN);
931
932 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
933 psh.dwSize = sizeof(PROPSHEETHEADER);
934 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
935 psh.hwndParent = hwndDlg;
936 psh.hInstance = hApplet;
937 psh.hIcon = NULL;
938 psh.pszCaption = szUserName;
939 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
940 psh.nStartPage = 0;
941 psh.ppsp = psp;
942
943 InitPropSheetPage(&psp[0], IDD_USER_GENERAL, (DLGPROC)UserGeneralPageProc, szUserName);
944 InitPropSheetPage(&psp[1], IDD_USER_MEMBERSHIP, (DLGPROC)UserMembershipPageProc, szUserName);
945 InitPropSheetPage(&psp[2], IDD_USER_PROFILE, (DLGPROC)UserProfilePageProc, szUserName);
946
947 return (PropertySheet(&psh) == IDOK);
948 }