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