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