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 ERR("NetUserSetInfo failed. 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 + 1]; 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 + 1); 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 + 1]; 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 + 1); 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 TRACE("Selected group: %s", dbgstrx(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 ERR("NetUserSetInfo failed. 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 + 1]; 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 + 1); 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 } 937