1 /* 2 * PROJECT: ReactOS msgina.dll 3 * FILE: dll/win32/msgina/gui.c 4 * PURPOSE: ReactOS Logon GINA DLL 5 * PROGRAMMER: Herv� Poussineau (hpoussin@reactos.org) 6 */ 7 8 #include "msgina.h" 9 10 #include <wingdi.h> 11 #include <winnls.h> 12 #include <winreg.h> 13 14 typedef struct _DISPLAYSTATUSMSG 15 { 16 PGINA_CONTEXT Context; 17 HDESK hDesktop; 18 DWORD dwOptions; 19 PWSTR pTitle; 20 PWSTR pMessage; 21 HANDLE StartupEvent; 22 } DISPLAYSTATUSMSG, *PDISPLAYSTATUSMSG; 23 24 typedef struct _LEGALNOTICEDATA 25 { 26 LPWSTR pszCaption; 27 LPWSTR pszText; 28 } LEGALNOTICEDATA, *PLEGALNOTICEDATA; 29 30 typedef struct _DLG_DATA 31 { 32 PGINA_CONTEXT pgContext; 33 HBITMAP hBitmap; 34 HBITMAP hBarBitmap; 35 UINT_PTR TimerID; 36 DWORD BarCounter; 37 DWORD BarWidth; 38 DWORD BarHeight; 39 } DLG_DATA, *PDLG_DATA; 40 41 static BOOL 42 GUIInitialize( 43 IN OUT PGINA_CONTEXT pgContext) 44 { 45 TRACE("GUIInitialize(%p)\n", pgContext); 46 return TRUE; 47 } 48 49 50 static 51 VOID 52 SetWelcomeText(HWND hWnd) 53 { 54 PWCHAR pBuffer = NULL, p; 55 HKEY hKey; 56 DWORD BufSize, dwType, dwWelcomeSize, dwTitleLength; 57 LONG rc; 58 59 TRACE("SetWelcomeText(%p)\n", hWnd); 60 61 /* Open the Winlogon key */ 62 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 63 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 64 0, 65 KEY_QUERY_VALUE, 66 &hKey); 67 if (rc != ERROR_SUCCESS) 68 { 69 WARN("RegOpenKeyExW() failed with error %lu\n", rc); 70 return; 71 } 72 73 /* Get the size of the Welcome value */ 74 dwWelcomeSize = 0; 75 rc = RegQueryValueExW(hKey, 76 L"Welcome", 77 NULL, 78 &dwType, 79 NULL, 80 &dwWelcomeSize); 81 if (rc == ERROR_FILE_NOT_FOUND || dwWelcomeSize == 0 || dwType != REG_SZ) 82 goto done; 83 84 dwTitleLength = GetWindowTextLengthW(hWnd); 85 BufSize = dwWelcomeSize + ((dwTitleLength + 1) * sizeof(WCHAR)); 86 87 pBuffer = HeapAlloc(GetProcessHeap(), 0, BufSize); 88 if (pBuffer == NULL) 89 goto done; 90 91 GetWindowTextW(hWnd, pBuffer, BufSize / sizeof(WCHAR)); 92 wcscat(pBuffer, L" "); 93 p = &pBuffer[dwTitleLength + 1]; 94 95 RegQueryValueExW(hKey, 96 L"Welcome", 97 NULL, 98 &dwType, 99 (PBYTE)p, 100 &dwWelcomeSize); 101 102 SetWindowText(hWnd, pBuffer); 103 104 done: 105 if (pBuffer != NULL) 106 HeapFree(GetProcessHeap(), 0, pBuffer); 107 108 RegCloseKey(hKey); 109 } 110 111 112 static INT_PTR CALLBACK 113 StatusDialogProc( 114 IN HWND hwndDlg, 115 IN UINT uMsg, 116 IN WPARAM wParam, 117 IN LPARAM lParam) 118 { 119 PDLG_DATA pDlgData; 120 UNREFERENCED_PARAMETER(wParam); 121 122 pDlgData = (PDLG_DATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 123 124 switch (uMsg) 125 { 126 case WM_INITDIALOG: 127 { 128 PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lParam; 129 if (!msg) 130 return FALSE; 131 132 msg->Context->hStatusWindow = hwndDlg; 133 134 if (msg->pTitle) 135 SetWindowTextW(hwndDlg, msg->pTitle); 136 SetDlgItemTextW(hwndDlg, IDC_STATUS_MESSAGE, msg->pMessage); 137 SetEvent(msg->StartupEvent); 138 139 pDlgData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DLG_DATA)); 140 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)pDlgData); 141 142 if (pDlgData == NULL) 143 return FALSE; 144 145 /* Load the bar bitmap */ 146 pDlgData->hBarBitmap = LoadImageW(hDllInstance, MAKEINTRESOURCEW(IDI_BAR), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 147 if (pDlgData->hBarBitmap) 148 { 149 BITMAP bm; 150 151 GetObject(pDlgData->hBarBitmap, sizeof(BITMAP), &bm); 152 pDlgData->BarWidth = bm.bmWidth; 153 pDlgData->BarHeight = bm.bmHeight; 154 pDlgData->TimerID = SetTimer(hwndDlg, -1, 20, NULL); 155 } 156 return TRUE; 157 } 158 159 case WM_TIMER: 160 { 161 if (pDlgData) 162 { 163 /* 164 * Default rotation bar image width is 413 (same as logo) 165 * We can divide 413 by 7 without remainder 166 */ 167 pDlgData->BarCounter = (pDlgData->BarCounter + 7) % pDlgData->BarWidth; 168 InvalidateRect(hwndDlg, NULL, FALSE); 169 UpdateWindow(hwndDlg); 170 } 171 return TRUE; 172 } 173 174 case WM_DRAWITEM: 175 { 176 LPDRAWITEMSTRUCT lpDis = (LPDRAWITEMSTRUCT)lParam; 177 178 if (lpDis->CtlID != IDC_BAR) 179 { 180 return FALSE; 181 } 182 183 if (pDlgData && pDlgData->hBarBitmap) 184 { 185 HDC hdcMem; 186 HGDIOBJ hOld; 187 DWORD off = pDlgData->BarCounter; 188 DWORD iw = pDlgData->BarWidth; 189 DWORD ih = pDlgData->BarHeight; 190 191 hdcMem = CreateCompatibleDC(lpDis->hDC); 192 hOld = SelectObject(hdcMem, pDlgData->hBarBitmap); 193 BitBlt(lpDis->hDC, off, 0, iw - off, ih, hdcMem, 0, 0, SRCCOPY); 194 BitBlt(lpDis->hDC, 0, 0, off, ih, hdcMem, iw - off, 0, SRCCOPY); 195 SelectObject(hdcMem, hOld); 196 DeleteDC(hdcMem); 197 198 return TRUE; 199 } 200 return FALSE; 201 } 202 203 case WM_DESTROY: 204 { 205 if (pDlgData) 206 { 207 if (pDlgData->hBarBitmap) 208 { 209 KillTimer(hwndDlg, pDlgData->TimerID); 210 DeleteObject(pDlgData->hBarBitmap); 211 } 212 HeapFree(GetProcessHeap(), 0, pDlgData); 213 } 214 return TRUE; 215 } 216 } 217 return FALSE; 218 } 219 220 static DWORD WINAPI 221 StartupWindowThread(LPVOID lpParam) 222 { 223 HDESK hDesk; 224 PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lpParam; 225 226 /* When SetThreadDesktop is called the system closes the desktop handle when needed 227 so we have to create a new handle because this handle may still be in use by winlogon */ 228 if (!DuplicateHandle ( GetCurrentProcess(), 229 msg->hDesktop, 230 GetCurrentProcess(), 231 (HANDLE*)&hDesk, 232 0, 233 FALSE, 234 DUPLICATE_SAME_ACCESS)) 235 { 236 ERR("Duplicating handle failed!\n"); 237 HeapFree(GetProcessHeap(), 0, lpParam); 238 return FALSE; 239 } 240 241 if(!SetThreadDesktop(hDesk)) 242 { 243 ERR("Setting thread desktop failed!\n"); 244 HeapFree(GetProcessHeap(), 0, lpParam); 245 return FALSE; 246 } 247 248 DialogBoxParamW( 249 hDllInstance, 250 MAKEINTRESOURCEW(IDD_STATUS), 251 GetDesktopWindow(), 252 StatusDialogProc, 253 (LPARAM)lpParam); 254 255 HeapFree(GetProcessHeap(), 0, lpParam); 256 return TRUE; 257 } 258 259 static BOOL 260 GUIDisplayStatusMessage( 261 IN PGINA_CONTEXT pgContext, 262 IN HDESK hDesktop, 263 IN DWORD dwOptions, 264 IN PWSTR pTitle, 265 IN PWSTR pMessage) 266 { 267 PDISPLAYSTATUSMSG msg; 268 HANDLE Thread; 269 DWORD ThreadId; 270 271 TRACE("GUIDisplayStatusMessage(%ws)\n", pMessage); 272 273 if (!pgContext->hStatusWindow) 274 { 275 /* 276 * If everything goes correctly, 'msg' is freed 277 * by the 'StartupWindowThread' thread. 278 */ 279 msg = (PDISPLAYSTATUSMSG)HeapAlloc(GetProcessHeap(), 280 HEAP_ZERO_MEMORY, 281 sizeof(*msg)); 282 if(!msg) 283 return FALSE; 284 285 msg->Context = pgContext; 286 msg->dwOptions = dwOptions; 287 msg->pTitle = pTitle; 288 msg->pMessage = pMessage; 289 msg->hDesktop = hDesktop; 290 291 msg->StartupEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 292 293 if (!msg->StartupEvent) 294 { 295 HeapFree(GetProcessHeap(), 0, msg); 296 return FALSE; 297 } 298 299 Thread = CreateThread(NULL, 300 0, 301 StartupWindowThread, 302 (PVOID)msg, 303 0, 304 &ThreadId); 305 if (Thread) 306 { 307 /* 'msg' will be freed by 'StartupWindowThread' */ 308 309 CloseHandle(Thread); 310 WaitForSingleObject(msg->StartupEvent, INFINITE); 311 CloseHandle(msg->StartupEvent); 312 return TRUE; 313 } 314 else 315 { 316 /* 317 * The 'StartupWindowThread' thread couldn't be created, 318 * so we need to free the allocated 'msg'. 319 */ 320 HeapFree(GetProcessHeap(), 0, msg); 321 } 322 323 return FALSE; 324 } 325 326 if (pTitle) 327 SetWindowTextW(pgContext->hStatusWindow, pTitle); 328 329 SetDlgItemTextW(pgContext->hStatusWindow, IDC_STATUS_MESSAGE, pMessage); 330 331 return TRUE; 332 } 333 334 static BOOL 335 GUIRemoveStatusMessage( 336 IN PGINA_CONTEXT pgContext) 337 { 338 if (pgContext->hStatusWindow) 339 { 340 EndDialog(pgContext->hStatusWindow, 0); 341 pgContext->hStatusWindow = NULL; 342 } 343 344 return TRUE; 345 } 346 347 static INT_PTR CALLBACK 348 WelcomeDialogProc( 349 IN HWND hwndDlg, 350 IN UINT uMsg, 351 IN WPARAM wParam, 352 IN LPARAM lParam) 353 { 354 PDLG_DATA pDlgData; 355 356 pDlgData = (PDLG_DATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 357 358 switch (uMsg) 359 { 360 case WM_INITDIALOG: 361 { 362 pDlgData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DLG_DATA)); 363 if (pDlgData == NULL) 364 return FALSE; 365 366 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)pDlgData); 367 368 pDlgData->pgContext = (PGINA_CONTEXT)lParam; 369 370 /* Load the logo bitmap */ 371 pDlgData->hBitmap = LoadImageW(pDlgData->pgContext->hDllInstance, MAKEINTRESOURCEW(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 372 return TRUE; 373 } 374 375 case WM_PAINT: 376 { 377 PAINTSTRUCT ps; 378 if (pDlgData->hBitmap) 379 { 380 BeginPaint(hwndDlg, &ps); 381 DrawStateW(ps.hdc, NULL, NULL, (LPARAM)pDlgData->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP); 382 EndPaint(hwndDlg, &ps); 383 } 384 return TRUE; 385 } 386 case WM_DESTROY: 387 { 388 DeleteObject(pDlgData->hBitmap); 389 HeapFree(GetProcessHeap(), 0, pDlgData); 390 return TRUE; 391 } 392 } 393 return FALSE; 394 } 395 396 static VOID 397 GUIDisplaySASNotice( 398 IN OUT PGINA_CONTEXT pgContext) 399 { 400 TRACE("GUIDisplaySASNotice()\n"); 401 402 /* Display the notice window */ 403 pgContext->pWlxFuncs->WlxDialogBoxParam(pgContext->hWlx, 404 pgContext->hDllInstance, 405 MAKEINTRESOURCEW(IDD_WELCOME), 406 GetDesktopWindow(), 407 WelcomeDialogProc, 408 (LPARAM)pgContext); 409 } 410 411 /* Get the text contained in a textbox. Allocates memory in pText 412 * to contain the text. Returns TRUE in case of success */ 413 static BOOL 414 GetTextboxText( 415 IN HWND hwndDlg, 416 IN INT TextboxId, 417 OUT LPWSTR *pText) 418 { 419 LPWSTR Text; 420 int Count; 421 422 Count = GetWindowTextLength(GetDlgItem(hwndDlg, TextboxId)); 423 Text = HeapAlloc(GetProcessHeap(), 0, (Count + 1) * sizeof(WCHAR)); 424 if (!Text) 425 return FALSE; 426 if (Count != GetWindowTextW(GetDlgItem(hwndDlg, TextboxId), Text, Count + 1)) 427 { 428 HeapFree(GetProcessHeap(), 0, Text); 429 return FALSE; 430 } 431 *pText = Text; 432 return TRUE; 433 } 434 435 436 static 437 INT 438 ResourceMessageBox( 439 IN PGINA_CONTEXT pgContext, 440 IN HWND hwnd, 441 IN UINT uType, 442 IN UINT uCaption, 443 IN UINT uText) 444 { 445 WCHAR szCaption[256]; 446 WCHAR szText[256]; 447 448 LoadStringW(pgContext->hDllInstance, uCaption, szCaption, _countof(szCaption)); 449 LoadStringW(pgContext->hDllInstance, uText, szText, _countof(szText)); 450 451 return pgContext->pWlxFuncs->WlxMessageBox(pgContext->hWlx, 452 hwnd, 453 szText, 454 szCaption, 455 uType); 456 } 457 458 459 static 460 BOOL 461 DoChangePassword( 462 IN PGINA_CONTEXT pgContext, 463 IN HWND hwndDlg) 464 { 465 WCHAR UserName[256]; 466 WCHAR Domain[256]; 467 WCHAR OldPassword[256]; 468 WCHAR NewPassword1[256]; 469 WCHAR NewPassword2[256]; 470 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer = NULL; 471 PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer = NULL; 472 ULONG RequestBufferSize; 473 ULONG ResponseBufferSize = 0; 474 LPWSTR Ptr; 475 BOOL res = FALSE; 476 NTSTATUS ProtocolStatus; 477 NTSTATUS Status; 478 479 GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_USERNAME, UserName, _countof(UserName)); 480 GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_DOMAIN, Domain, _countof(Domain)); 481 GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_OLDPWD, OldPassword, _countof(OldPassword)); 482 GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_NEWPWD1, NewPassword1, _countof(NewPassword1)); 483 GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_NEWPWD2, NewPassword2, _countof(NewPassword2)); 484 485 /* Compare the two passwords and fail if they do not match */ 486 if (wcscmp(NewPassword1, NewPassword2) != 0) 487 { 488 ResourceMessageBox(pgContext, 489 hwndDlg, 490 MB_OK | MB_ICONEXCLAMATION, 491 IDS_CHANGEPWDTITLE, 492 IDS_NONMATCHINGPASSWORDS); 493 return FALSE; 494 } 495 496 /* Calculate the request buffer size */ 497 RequestBufferSize = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) + 498 ((wcslen(Domain) + 1) * sizeof(WCHAR)) + 499 ((wcslen(UserName) + 1) * sizeof(WCHAR)) + 500 ((wcslen(OldPassword) + 1) * sizeof(WCHAR)) + 501 ((wcslen(NewPassword1) + 1) * sizeof(WCHAR)); 502 503 /* Allocate the request buffer */ 504 RequestBuffer = HeapAlloc(GetProcessHeap(), 505 HEAP_ZERO_MEMORY, 506 RequestBufferSize); 507 if (RequestBuffer == NULL) 508 { 509 ERR("HeapAlloc failed\n"); 510 return FALSE; 511 } 512 513 /* Initialize the request buffer */ 514 RequestBuffer->MessageType = MsV1_0ChangePassword; 515 RequestBuffer->Impersonating = TRUE; 516 517 Ptr = (LPWSTR)((ULONG_PTR)RequestBuffer + sizeof(MSV1_0_CHANGEPASSWORD_REQUEST)); 518 519 /* Pack the domain name */ 520 RequestBuffer->DomainName.Length = wcslen(Domain) * sizeof(WCHAR); 521 RequestBuffer->DomainName.MaximumLength = RequestBuffer->DomainName.Length + sizeof(WCHAR); 522 RequestBuffer->DomainName.Buffer = Ptr; 523 524 RtlCopyMemory(RequestBuffer->DomainName.Buffer, 525 Domain, 526 RequestBuffer->DomainName.MaximumLength); 527 528 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->DomainName.MaximumLength); 529 530 /* Pack the user name */ 531 RequestBuffer->AccountName.Length = wcslen(UserName) * sizeof(WCHAR); 532 RequestBuffer->AccountName.MaximumLength = RequestBuffer->AccountName.Length + sizeof(WCHAR); 533 RequestBuffer->AccountName.Buffer = Ptr; 534 535 RtlCopyMemory(RequestBuffer->AccountName.Buffer, 536 UserName, 537 RequestBuffer->AccountName.MaximumLength); 538 539 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->AccountName.MaximumLength); 540 541 /* Pack the old password */ 542 RequestBuffer->OldPassword.Length = wcslen(OldPassword) * sizeof(WCHAR); 543 RequestBuffer->OldPassword.MaximumLength = RequestBuffer->OldPassword.Length + sizeof(WCHAR); 544 RequestBuffer->OldPassword.Buffer = Ptr; 545 546 RtlCopyMemory(RequestBuffer->OldPassword.Buffer, 547 OldPassword, 548 RequestBuffer->OldPassword.MaximumLength); 549 550 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->OldPassword.MaximumLength); 551 552 /* Pack the new password */ 553 RequestBuffer->NewPassword.Length = wcslen(NewPassword1) * sizeof(WCHAR); 554 RequestBuffer->NewPassword.MaximumLength = RequestBuffer->NewPassword.Length + sizeof(WCHAR); 555 RequestBuffer->NewPassword.Buffer = Ptr; 556 557 RtlCopyMemory(RequestBuffer->NewPassword.Buffer, 558 NewPassword1, 559 RequestBuffer->NewPassword.MaximumLength); 560 561 /* Connect to the LSA server */ 562 if (ConnectToLsa(pgContext) != ERROR_SUCCESS) 563 { 564 ERR("ConnectToLsa() failed\n"); 565 goto done; 566 } 567 568 /* Call the authentication package */ 569 Status = LsaCallAuthenticationPackage(pgContext->LsaHandle, 570 pgContext->AuthenticationPackage, 571 RequestBuffer, 572 RequestBufferSize, 573 (PVOID*)&ResponseBuffer, 574 &ResponseBufferSize, 575 &ProtocolStatus); 576 if (!NT_SUCCESS(Status)) 577 { 578 ERR("LsaCallAuthenticationPackage failed (Status 0x%08lx)\n", Status); 579 goto done; 580 } 581 582 if (!NT_SUCCESS(ProtocolStatus)) 583 { 584 TRACE("LsaCallAuthenticationPackage failed (ProtocolStatus 0x%08lx)\n", ProtocolStatus); 585 goto done; 586 } 587 588 res = TRUE; 589 590 ResourceMessageBox(pgContext, 591 hwndDlg, 592 MB_OK | MB_ICONINFORMATION, 593 IDS_CHANGEPWDTITLE, 594 IDS_PASSWORDCHANGED); 595 596 if ((wcscmp(UserName, pgContext->UserName) == 0) && 597 (wcscmp(Domain, pgContext->DomainName) == 0) && 598 (wcscmp(OldPassword, pgContext->Password) == 0)) 599 { 600 ZeroMemory(pgContext->Password, sizeof(pgContext->Password)); 601 wcscpy(pgContext->Password, NewPassword1); 602 } 603 604 done: 605 if (RequestBuffer != NULL) 606 HeapFree(GetProcessHeap(), 0, RequestBuffer); 607 608 if (ResponseBuffer != NULL) 609 LsaFreeReturnBuffer(ResponseBuffer); 610 611 return res; 612 } 613 614 615 static INT_PTR CALLBACK 616 ChangePasswordDialogProc( 617 IN HWND hwndDlg, 618 IN UINT uMsg, 619 IN WPARAM wParam, 620 IN LPARAM lParam) 621 { 622 PGINA_CONTEXT pgContext; 623 624 pgContext = (PGINA_CONTEXT)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 625 626 switch (uMsg) 627 { 628 case WM_INITDIALOG: 629 { 630 pgContext = (PGINA_CONTEXT)lParam; 631 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)pgContext); 632 633 SetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_USERNAME, pgContext->UserName); 634 SendDlgItemMessageW(hwndDlg, IDC_CHANGEPWD_DOMAIN, CB_ADDSTRING, 0, (LPARAM)pgContext->DomainName); 635 SendDlgItemMessageW(hwndDlg, IDC_CHANGEPWD_DOMAIN, CB_SETCURSEL, 0, 0); 636 SetFocus(GetDlgItem(hwndDlg, IDC_CHANGEPWD_OLDPWD)); 637 return TRUE; 638 } 639 640 case WM_COMMAND: 641 switch (LOWORD(wParam)) 642 { 643 case IDOK: 644 if (DoChangePassword(pgContext, hwndDlg)) 645 { 646 EndDialog(hwndDlg, TRUE); 647 } 648 else 649 { 650 SetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_NEWPWD1, NULL); 651 SetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_NEWPWD2, NULL); 652 SetFocus(GetDlgItem(hwndDlg, IDC_CHANGEPWD_OLDPWD)); 653 } 654 return TRUE; 655 656 case IDCANCEL: 657 EndDialog(hwndDlg, FALSE); 658 return TRUE; 659 } 660 break; 661 662 case WM_CLOSE: 663 EndDialog(hwndDlg, FALSE); 664 return TRUE; 665 } 666 667 return FALSE; 668 } 669 670 671 static VOID 672 OnInitSecurityDlg(HWND hwnd, 673 PGINA_CONTEXT pgContext) 674 { 675 WCHAR Buffer1[256]; 676 WCHAR Buffer2[256]; 677 WCHAR Buffer3[256]; 678 WCHAR Buffer4[512]; 679 680 LoadStringW(pgContext->hDllInstance, IDS_LOGONMSG, Buffer1, _countof(Buffer1)); 681 682 wsprintfW(Buffer2, L"%s\\%s", pgContext->DomainName, pgContext->UserName); 683 wsprintfW(Buffer4, Buffer1, Buffer2); 684 685 SetDlgItemTextW(hwnd, IDC_SECURITY_MESSAGE, Buffer4); 686 687 LoadStringW(pgContext->hDllInstance, IDS_LOGONDATE, Buffer1, _countof(Buffer1)); 688 689 GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, 690 (SYSTEMTIME*)&pgContext->LogonTime, NULL, Buffer2, _countof(Buffer2)); 691 692 GetTimeFormatW(LOCALE_USER_DEFAULT, 0, 693 (SYSTEMTIME*)&pgContext->LogonTime, NULL, Buffer3, _countof(Buffer3)); 694 695 wsprintfW(Buffer4, Buffer1, Buffer2, Buffer3); 696 697 SetDlgItemTextW(hwnd, IDC_SECURITY_LOGONDATE, Buffer4); 698 699 if (pgContext->bAutoAdminLogon) 700 EnableWindow(GetDlgItem(hwnd, IDC_SECURITY_LOGOFF), FALSE); 701 } 702 703 704 static BOOL 705 OnChangePassword( 706 IN HWND hwnd, 707 IN PGINA_CONTEXT pgContext) 708 { 709 INT res; 710 711 TRACE("OnChangePassword()\n"); 712 713 res = pgContext->pWlxFuncs->WlxDialogBoxParam( 714 pgContext->hWlx, 715 pgContext->hDllInstance, 716 MAKEINTRESOURCEW(IDD_CHANGEPWD), 717 hwnd, 718 ChangePasswordDialogProc, 719 (LPARAM)pgContext); 720 721 TRACE("Result: %x\n", res); 722 723 return FALSE; 724 } 725 726 727 static INT_PTR CALLBACK 728 LogOffDialogProc( 729 IN HWND hwndDlg, 730 IN UINT uMsg, 731 IN WPARAM wParam, 732 IN LPARAM lParam) 733 { 734 switch (uMsg) 735 { 736 case WM_INITDIALOG: 737 return TRUE; 738 739 case WM_COMMAND: 740 switch (LOWORD(wParam)) 741 { 742 case IDYES: 743 EndDialog(hwndDlg, IDYES); 744 return TRUE; 745 746 case IDNO: 747 EndDialog(hwndDlg, IDNO); 748 return TRUE; 749 } 750 break; 751 752 case WM_CLOSE: 753 EndDialog(hwndDlg, IDNO); 754 return TRUE; 755 } 756 757 return FALSE; 758 } 759 760 761 static 762 INT 763 OnLogOff( 764 IN HWND hwndDlg, 765 IN PGINA_CONTEXT pgContext) 766 { 767 return pgContext->pWlxFuncs->WlxDialogBoxParam( 768 pgContext->hWlx, 769 pgContext->hDllInstance, 770 MAKEINTRESOURCEW(IDD_LOGOFF), 771 hwndDlg, 772 LogOffDialogProc, 773 (LPARAM)pgContext); 774 } 775 776 777 static 778 INT 779 OnShutDown( 780 IN HWND hwndDlg, 781 IN PGINA_CONTEXT pgContext) 782 { 783 INT ret; 784 DWORD ShutdownOptions; 785 786 TRACE("OnShutDown(%p %p)\n", hwndDlg, pgContext); 787 788 pgContext->nShutdownAction = GetDefaultShutdownSelState(); 789 ShutdownOptions = GetDefaultShutdownOptions(); 790 791 if (pgContext->UserToken != NULL) 792 { 793 if (ImpersonateLoggedOnUser(pgContext->UserToken)) 794 { 795 pgContext->nShutdownAction = LoadShutdownSelState(); 796 ShutdownOptions = GetAllowedShutdownOptions(); 797 RevertToSelf(); 798 } 799 else 800 { 801 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError()); 802 } 803 } 804 805 ret = ShutdownDialog(hwndDlg, ShutdownOptions, pgContext); 806 807 if (ret == IDOK) 808 { 809 if (pgContext->UserToken != NULL) 810 { 811 if (ImpersonateLoggedOnUser(pgContext->UserToken)) 812 { 813 SaveShutdownSelState(pgContext->nShutdownAction); 814 RevertToSelf(); 815 } 816 else 817 { 818 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError()); 819 } 820 } 821 } 822 823 return ret; 824 } 825 826 827 static INT_PTR CALLBACK 828 SecurityDialogProc( 829 IN HWND hwndDlg, 830 IN UINT uMsg, 831 IN WPARAM wParam, 832 IN LPARAM lParam) 833 { 834 PGINA_CONTEXT pgContext; 835 836 pgContext = (PGINA_CONTEXT)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 837 838 switch (uMsg) 839 { 840 case WM_INITDIALOG: 841 { 842 pgContext = (PGINA_CONTEXT)lParam; 843 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)pgContext); 844 845 SetWelcomeText(hwndDlg); 846 847 OnInitSecurityDlg(hwndDlg, (PGINA_CONTEXT)lParam); 848 SetFocus(GetDlgItem(hwndDlg, IDNO)); 849 return TRUE; 850 } 851 852 case WM_COMMAND: 853 { 854 switch (LOWORD(wParam)) 855 { 856 case IDC_SECURITY_LOCK: 857 EndDialog(hwndDlg, WLX_SAS_ACTION_LOCK_WKSTA); 858 return TRUE; 859 case IDC_SECURITY_LOGOFF: 860 if (OnLogOff(hwndDlg, pgContext) == IDYES) 861 EndDialog(hwndDlg, WLX_SAS_ACTION_LOGOFF); 862 return TRUE; 863 case IDC_SECURITY_SHUTDOWN: 864 if (OnShutDown(hwndDlg, pgContext) == IDOK) 865 EndDialog(hwndDlg, pgContext->nShutdownAction); 866 return TRUE; 867 case IDC_SECURITY_CHANGEPWD: 868 if (OnChangePassword(hwndDlg, pgContext)) 869 EndDialog(hwndDlg, WLX_SAS_ACTION_PWD_CHANGED); 870 return TRUE; 871 case IDC_SECURITY_TASKMGR: 872 EndDialog(hwndDlg, WLX_SAS_ACTION_TASKLIST); 873 return TRUE; 874 case IDCANCEL: 875 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); 876 return TRUE; 877 } 878 break; 879 } 880 case WM_CLOSE: 881 { 882 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); 883 return TRUE; 884 } 885 } 886 887 return FALSE; 888 } 889 890 static INT 891 GUILoggedOnSAS( 892 IN OUT PGINA_CONTEXT pgContext, 893 IN DWORD dwSasType) 894 { 895 INT result; 896 897 TRACE("GUILoggedOnSAS()\n"); 898 899 if (dwSasType != WLX_SAS_TYPE_CTRL_ALT_DEL) 900 { 901 /* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will 902 * close itself thanks to the use of WlxDialogBoxParam */ 903 return WLX_SAS_ACTION_NONE; 904 } 905 906 pgContext->pWlxFuncs->WlxSwitchDesktopToWinlogon( 907 pgContext->hWlx); 908 909 result = pgContext->pWlxFuncs->WlxDialogBoxParam( 910 pgContext->hWlx, 911 pgContext->hDllInstance, 912 MAKEINTRESOURCEW(IDD_SECURITY), 913 GetDesktopWindow(), 914 SecurityDialogProc, 915 (LPARAM)pgContext); 916 917 if (result < WLX_SAS_ACTION_LOGON || 918 result > WLX_SAS_ACTION_SWITCH_CONSOLE) 919 { 920 result = WLX_SAS_ACTION_NONE; 921 } 922 923 if (result == WLX_SAS_ACTION_NONE) 924 { 925 pgContext->pWlxFuncs->WlxSwitchDesktopToUser( 926 pgContext->hWlx); 927 } 928 929 return result; 930 } 931 932 933 static 934 BOOL 935 DoLogon( 936 IN HWND hwndDlg, 937 IN OUT PGINA_CONTEXT pgContext) 938 { 939 LPWSTR UserName = NULL; 940 LPWSTR Password = NULL; 941 LPWSTR Domain = NULL; 942 BOOL result = FALSE; 943 NTSTATUS Status, SubStatus = STATUS_SUCCESS; 944 945 if (GetTextboxText(hwndDlg, IDC_LOGON_USERNAME, &UserName) && *UserName == '\0') 946 goto done; 947 948 if (GetTextboxText(hwndDlg, IDC_LOGON_DOMAIN, &Domain) && *Domain == '\0') 949 goto done; 950 951 if (!GetTextboxText(hwndDlg, IDC_LOGON_PASSWORD, &Password)) 952 goto done; 953 954 Status = DoLoginTasks(pgContext, UserName, Domain, Password, &SubStatus); 955 if (Status == STATUS_LOGON_FAILURE) 956 { 957 ResourceMessageBox(pgContext, 958 hwndDlg, 959 MB_OK | MB_ICONEXCLAMATION, 960 IDS_LOGONTITLE, 961 IDS_LOGONWRONGUSERORPWD); 962 goto done; 963 } 964 else if (Status == STATUS_ACCOUNT_RESTRICTION) 965 { 966 TRACE("DoLoginTasks failed! Status 0x%08lx SubStatus 0x%08lx\n", Status, SubStatus); 967 968 if (SubStatus == STATUS_ACCOUNT_DISABLED) 969 { 970 ResourceMessageBox(pgContext, 971 hwndDlg, 972 MB_OK | MB_ICONEXCLAMATION, 973 IDS_LOGONTITLE, 974 IDS_LOGONUSERDISABLED); 975 goto done; 976 } 977 else if (SubStatus == STATUS_ACCOUNT_LOCKED_OUT) 978 { 979 TRACE("Account locked!\n"); 980 pgContext->pWlxFuncs->WlxMessageBox(pgContext->hWlx, 981 hwndDlg, 982 L"Account locked!", 983 L"Logon error", 984 MB_OK | MB_ICONERROR); 985 goto done; 986 } 987 else if ((SubStatus == STATUS_PASSWORD_MUST_CHANGE) || 988 (SubStatus == STATUS_PASSWORD_EXPIRED)) 989 { 990 if (SubStatus == STATUS_PASSWORD_MUST_CHANGE) 991 ResourceMessageBox(pgContext, 992 hwndDlg, 993 MB_OK | MB_ICONSTOP, 994 IDS_LOGONTITLE, 995 IDS_PASSWORDMUSTCHANGE); 996 else 997 ResourceMessageBox(pgContext, 998 hwndDlg, 999 MB_OK | MB_ICONSTOP, 1000 IDS_LOGONTITLE, 1001 IDS_PASSWORDEXPIRED); 1002 1003 if (!OnChangePassword(hwndDlg, 1004 pgContext)) 1005 goto done; 1006 1007 Status = DoLoginTasks(pgContext, 1008 pgContext->UserName, 1009 pgContext->DomainName, 1010 pgContext->Password, 1011 &SubStatus); 1012 if (!NT_SUCCESS(Status)) 1013 { 1014 TRACE("Login after password change failed! (Status 0x%08lx)\n", Status); 1015 1016 goto done; 1017 } 1018 } 1019 else if (SubStatus == STATUS_ACCOUNT_EXPIRED) 1020 { 1021 ResourceMessageBox(pgContext, 1022 hwndDlg, 1023 MB_OK | MB_ICONEXCLAMATION, 1024 IDS_LOGONTITLE, 1025 IDS_ACCOUNTEXPIRED); 1026 } 1027 else 1028 { 1029 TRACE("Other error!\n"); 1030 pgContext->pWlxFuncs->WlxMessageBox(pgContext->hWlx, 1031 hwndDlg, 1032 L"Other error!", 1033 L"Logon error", 1034 MB_OK | MB_ICONERROR); 1035 goto done; 1036 } 1037 } 1038 else if (!NT_SUCCESS(Status)) 1039 { 1040 TRACE("DoLoginTasks failed! Status 0x%08lx\n", Status); 1041 goto done; 1042 } 1043 1044 1045 if (!CreateProfile(pgContext, UserName, Domain, Password)) 1046 { 1047 ERR("Failed to create the profile!\n"); 1048 goto done; 1049 } 1050 1051 ZeroMemory(pgContext->Password, sizeof(pgContext->Password)); 1052 wcscpy(pgContext->Password, Password); 1053 1054 result = TRUE; 1055 1056 done: 1057 pgContext->bAutoAdminLogon = FALSE; 1058 1059 if (UserName != NULL) 1060 HeapFree(GetProcessHeap(), 0, UserName); 1061 1062 if (Password != NULL) 1063 HeapFree(GetProcessHeap(), 0, Password); 1064 1065 if (Domain != NULL) 1066 HeapFree(GetProcessHeap(), 0, Domain); 1067 1068 return result; 1069 } 1070 1071 1072 static 1073 VOID 1074 SetDomainComboBox( 1075 HWND hwndDomainComboBox, 1076 PGINA_CONTEXT pgContext) 1077 { 1078 WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1]; 1079 DWORD dwComputerNameLength; 1080 LONG lIndex = 0; 1081 LONG lFindIndex; 1082 1083 SendMessageW(hwndDomainComboBox, CB_RESETCONTENT, 0, 0); 1084 1085 dwComputerNameLength = _countof(szComputerName); 1086 if (GetComputerNameW(szComputerName, &dwComputerNameLength)) 1087 { 1088 lIndex = SendMessageW(hwndDomainComboBox, CB_ADDSTRING, 0, (LPARAM)szComputerName); 1089 } 1090 1091 if (wcslen(pgContext->DomainName) != 0) 1092 { 1093 lFindIndex = SendMessageW(hwndDomainComboBox, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)pgContext->DomainName); 1094 if (lFindIndex == CB_ERR) 1095 { 1096 lIndex = SendMessageW(hwndDomainComboBox, CB_ADDSTRING, 0, (LPARAM)pgContext->DomainName); 1097 } 1098 else 1099 { 1100 lIndex = lFindIndex; 1101 } 1102 } 1103 1104 SendMessageW(hwndDomainComboBox, CB_SETCURSEL, lIndex, 0); 1105 } 1106 1107 1108 static INT_PTR CALLBACK 1109 LogonDialogProc( 1110 IN HWND hwndDlg, 1111 IN UINT uMsg, 1112 IN WPARAM wParam, 1113 IN LPARAM lParam) 1114 { 1115 PDLG_DATA pDlgData; 1116 1117 pDlgData = (PDLG_DATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 1118 1119 switch (uMsg) 1120 { 1121 case WM_INITDIALOG: 1122 { 1123 pDlgData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DLG_DATA)); 1124 if (pDlgData == NULL) 1125 return FALSE; 1126 1127 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)pDlgData); 1128 1129 /* FIXME: take care of NoDomainUI */ 1130 pDlgData->pgContext = (PGINA_CONTEXT)lParam; 1131 1132 /* Draw the logo bitmap */ 1133 pDlgData->hBitmap = LoadImageW(pDlgData->pgContext->hDllInstance, MAKEINTRESOURCEW(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 1134 1135 SetWelcomeText(hwndDlg); 1136 1137 if (pDlgData->pgContext->bAutoAdminLogon || 1138 !pDlgData->pgContext->bDontDisplayLastUserName) 1139 SetDlgItemTextW(hwndDlg, IDC_LOGON_USERNAME, pDlgData->pgContext->UserName); 1140 1141 if (pDlgData->pgContext->bAutoAdminLogon) 1142 SetDlgItemTextW(hwndDlg, IDC_LOGON_PASSWORD, pDlgData->pgContext->Password); 1143 1144 SetDomainComboBox(GetDlgItem(hwndDlg, IDC_LOGON_DOMAIN), pDlgData->pgContext); 1145 1146 if (pDlgData->pgContext->bDisableCAD) 1147 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE); 1148 1149 if (!pDlgData->pgContext->bShutdownWithoutLogon) 1150 EnableWindow(GetDlgItem(hwndDlg, IDC_LOGON_SHUTDOWN), FALSE); 1151 1152 SetFocus(GetDlgItem(hwndDlg, pDlgData->pgContext->bDontDisplayLastUserName ? IDC_LOGON_USERNAME : IDC_LOGON_PASSWORD)); 1153 1154 if (pDlgData->pgContext->bAutoAdminLogon) 1155 PostMessage(GetDlgItem(hwndDlg, IDOK), BM_CLICK, 0, 0); 1156 1157 return TRUE; 1158 } 1159 1160 case WM_PAINT: 1161 { 1162 PAINTSTRUCT ps; 1163 if (pDlgData->hBitmap) 1164 { 1165 BeginPaint(hwndDlg, &ps); 1166 DrawStateW(ps.hdc, NULL, NULL, (LPARAM)pDlgData->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP); 1167 EndPaint(hwndDlg, &ps); 1168 } 1169 return TRUE; 1170 } 1171 1172 case WM_DESTROY: 1173 DeleteObject(pDlgData->hBitmap); 1174 HeapFree(GetProcessHeap(), 0, pDlgData); 1175 return TRUE; 1176 1177 case WM_COMMAND: 1178 switch (LOWORD(wParam)) 1179 { 1180 case IDOK: 1181 if (DoLogon(hwndDlg, pDlgData->pgContext)) 1182 EndDialog(hwndDlg, WLX_SAS_ACTION_LOGON); 1183 return TRUE; 1184 1185 case IDCANCEL: 1186 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); 1187 return TRUE; 1188 1189 case IDC_LOGON_SHUTDOWN: 1190 if (OnShutDown(hwndDlg, pDlgData->pgContext) == IDOK) 1191 EndDialog(hwndDlg, pDlgData->pgContext->nShutdownAction); 1192 return TRUE; 1193 } 1194 break; 1195 } 1196 1197 return FALSE; 1198 } 1199 1200 1201 static 1202 INT_PTR 1203 CALLBACK 1204 LegalNoticeDialogProc( 1205 IN HWND hwndDlg, 1206 IN UINT uMsg, 1207 IN WPARAM wParam, 1208 IN LPARAM lParam) 1209 { 1210 PLEGALNOTICEDATA pLegalNotice; 1211 1212 switch (uMsg) 1213 { 1214 case WM_INITDIALOG: 1215 pLegalNotice = (PLEGALNOTICEDATA)lParam; 1216 SetWindowTextW(hwndDlg, pLegalNotice->pszCaption); 1217 SetDlgItemTextW(hwndDlg, IDC_LEGALNOTICE_TEXT, pLegalNotice->pszText); 1218 return TRUE; 1219 1220 case WM_COMMAND: 1221 switch (LOWORD(wParam)) 1222 { 1223 case IDOK: 1224 EndDialog(hwndDlg, 0); 1225 return TRUE; 1226 1227 case IDCANCEL: 1228 EndDialog(hwndDlg, 0); 1229 return TRUE; 1230 } 1231 break; 1232 } 1233 1234 return FALSE; 1235 } 1236 1237 1238 static INT 1239 GUILoggedOutSAS( 1240 IN OUT PGINA_CONTEXT pgContext) 1241 { 1242 LEGALNOTICEDATA LegalNotice = {NULL, NULL}; 1243 HKEY hKey = NULL; 1244 LONG rc; 1245 int result; 1246 1247 TRACE("GUILoggedOutSAS()\n"); 1248 1249 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1250 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 1251 0, 1252 KEY_QUERY_VALUE, 1253 &hKey); 1254 if (rc == ERROR_SUCCESS) 1255 { 1256 ReadRegSzValue(hKey, 1257 L"LegalNoticeCaption", 1258 &LegalNotice.pszCaption); 1259 1260 ReadRegSzValue(hKey, 1261 L"LegalNoticeText", 1262 &LegalNotice.pszText); 1263 1264 RegCloseKey(hKey); 1265 } 1266 1267 if (LegalNotice.pszCaption != NULL && wcslen(LegalNotice.pszCaption) != 0 && 1268 LegalNotice.pszText != NULL && wcslen(LegalNotice.pszText) != 0) 1269 { 1270 pgContext->pWlxFuncs->WlxDialogBoxParam(pgContext->hWlx, 1271 pgContext->hDllInstance, 1272 MAKEINTRESOURCEW(IDD_LEGALNOTICE), 1273 GetDesktopWindow(), 1274 LegalNoticeDialogProc, 1275 (LPARAM)&LegalNotice); 1276 } 1277 1278 if (LegalNotice.pszCaption != NULL) 1279 HeapFree(GetProcessHeap(), 0, LegalNotice.pszCaption); 1280 1281 if (LegalNotice.pszText != NULL) 1282 HeapFree(GetProcessHeap(), 0, LegalNotice.pszText); 1283 1284 result = pgContext->pWlxFuncs->WlxDialogBoxParam( 1285 pgContext->hWlx, 1286 pgContext->hDllInstance, 1287 MAKEINTRESOURCEW(IDD_LOGON), 1288 GetDesktopWindow(), 1289 LogonDialogProc, 1290 (LPARAM)pgContext); 1291 if (result >= WLX_SAS_ACTION_LOGON && 1292 result <= WLX_SAS_ACTION_SWITCH_CONSOLE) 1293 { 1294 WARN("WlxLoggedOutSAS() returns 0x%x\n", result); 1295 return result; 1296 } 1297 1298 WARN("WlxDialogBoxParam() failed (0x%x)\n", result); 1299 return WLX_SAS_ACTION_NONE; 1300 } 1301 1302 1303 static VOID 1304 SetLockMessage(HWND hwnd, 1305 INT nDlgItem, 1306 PGINA_CONTEXT pgContext) 1307 { 1308 WCHAR Buffer1[256]; 1309 WCHAR Buffer2[256]; 1310 WCHAR Buffer3[512]; 1311 1312 LoadStringW(pgContext->hDllInstance, IDS_LOCKMSG, Buffer1, _countof(Buffer1)); 1313 1314 wsprintfW(Buffer2, L"%s\\%s", pgContext->DomainName, pgContext->UserName); 1315 wsprintfW(Buffer3, Buffer1, Buffer2); 1316 1317 SetDlgItemTextW(hwnd, nDlgItem, Buffer3); 1318 } 1319 1320 1321 static 1322 BOOL 1323 DoUnlock( 1324 IN HWND hwndDlg, 1325 IN PGINA_CONTEXT pgContext, 1326 OUT LPINT Action) 1327 { 1328 WCHAR Buffer1[256]; 1329 WCHAR Buffer2[256]; 1330 LPWSTR UserName = NULL; 1331 LPWSTR Password = NULL; 1332 BOOL res = FALSE; 1333 1334 if (GetTextboxText(hwndDlg, IDC_UNLOCK_USERNAME, &UserName) && *UserName == '\0') 1335 { 1336 HeapFree(GetProcessHeap(), 0, UserName); 1337 return FALSE; 1338 } 1339 1340 if (GetTextboxText(hwndDlg, IDC_UNLOCK_PASSWORD, &Password)) 1341 { 1342 if (UserName != NULL && Password != NULL && 1343 wcscmp(UserName, pgContext->UserName) == 0 && 1344 wcscmp(Password, pgContext->Password) == 0) 1345 { 1346 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA; 1347 res = TRUE; 1348 } 1349 else if (wcscmp(UserName, pgContext->UserName) == 0 && 1350 wcscmp(Password, pgContext->Password) != 0) 1351 { 1352 /* Wrong Password */ 1353 LoadStringW(pgContext->hDllInstance, IDS_LOCKEDWRONGPASSWORD, Buffer2, _countof(Buffer2)); 1354 LoadStringW(pgContext->hDllInstance, IDS_COMPUTERLOCKED, Buffer1, _countof(Buffer1)); 1355 MessageBoxW(hwndDlg, Buffer2, Buffer1, MB_OK | MB_ICONERROR); 1356 } 1357 else 1358 { 1359 /* Wrong user name */ 1360 if (DoAdminUnlock(pgContext, UserName, NULL, Password)) 1361 { 1362 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA; 1363 res = TRUE; 1364 } 1365 else 1366 { 1367 LoadStringW(pgContext->hDllInstance, IDS_LOCKEDWRONGUSER, Buffer1, _countof(Buffer1)); 1368 wsprintfW(Buffer2, Buffer1, pgContext->DomainName, pgContext->UserName); 1369 LoadStringW(pgContext->hDllInstance, IDS_COMPUTERLOCKED, Buffer1, _countof(Buffer1)); 1370 MessageBoxW(hwndDlg, Buffer2, Buffer1, MB_OK | MB_ICONERROR); 1371 } 1372 } 1373 } 1374 1375 if (UserName != NULL) 1376 HeapFree(GetProcessHeap(), 0, UserName); 1377 1378 if (Password != NULL) 1379 HeapFree(GetProcessHeap(), 0, Password); 1380 1381 return res; 1382 } 1383 1384 1385 static 1386 INT_PTR 1387 CALLBACK 1388 UnlockDialogProc( 1389 IN HWND hwndDlg, 1390 IN UINT uMsg, 1391 IN WPARAM wParam, 1392 IN LPARAM lParam) 1393 { 1394 PDLG_DATA pDlgData; 1395 INT result = WLX_SAS_ACTION_NONE; 1396 1397 pDlgData = (PDLG_DATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 1398 1399 switch (uMsg) 1400 { 1401 case WM_INITDIALOG: 1402 { 1403 pDlgData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DLG_DATA)); 1404 if (pDlgData == NULL) 1405 return FALSE; 1406 1407 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)pDlgData); 1408 1409 pDlgData->pgContext = (PGINA_CONTEXT)lParam; 1410 1411 SetWelcomeText(hwndDlg); 1412 1413 SetLockMessage(hwndDlg, IDC_UNLOCK_MESSAGE, pDlgData->pgContext); 1414 1415 SetDlgItemTextW(hwndDlg, IDC_UNLOCK_USERNAME, pDlgData->pgContext->UserName); 1416 SetFocus(GetDlgItem(hwndDlg, IDC_UNLOCK_PASSWORD)); 1417 1418 if (pDlgData->pgContext->bDisableCAD) 1419 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE); 1420 1421 /* Load the logo bitmap */ 1422 pDlgData->hBitmap = LoadImageW(pDlgData->pgContext->hDllInstance, MAKEINTRESOURCEW(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 1423 return TRUE; 1424 } 1425 1426 case WM_PAINT: 1427 { 1428 PAINTSTRUCT ps; 1429 if (pDlgData->hBitmap) 1430 { 1431 BeginPaint(hwndDlg, &ps); 1432 DrawStateW(ps.hdc, NULL, NULL, (LPARAM)pDlgData->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP); 1433 EndPaint(hwndDlg, &ps); 1434 } 1435 return TRUE; 1436 } 1437 case WM_DESTROY: 1438 DeleteObject(pDlgData->hBitmap); 1439 HeapFree(GetProcessHeap(), 0, pDlgData); 1440 return TRUE; 1441 1442 case WM_COMMAND: 1443 switch (LOWORD(wParam)) 1444 { 1445 case IDOK: 1446 if (DoUnlock(hwndDlg, pDlgData->pgContext, &result)) 1447 EndDialog(hwndDlg, result); 1448 return TRUE; 1449 1450 case IDCANCEL: 1451 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); 1452 return TRUE; 1453 } 1454 break; 1455 } 1456 1457 return FALSE; 1458 } 1459 1460 1461 static INT 1462 GUILockedSAS( 1463 IN OUT PGINA_CONTEXT pgContext) 1464 { 1465 int result; 1466 1467 TRACE("GUILockedSAS()\n"); 1468 1469 result = pgContext->pWlxFuncs->WlxDialogBoxParam( 1470 pgContext->hWlx, 1471 pgContext->hDllInstance, 1472 MAKEINTRESOURCEW(IDD_UNLOCK), 1473 GetDesktopWindow(), 1474 UnlockDialogProc, 1475 (LPARAM)pgContext); 1476 if (result >= WLX_SAS_ACTION_LOGON && 1477 result <= WLX_SAS_ACTION_SWITCH_CONSOLE) 1478 { 1479 WARN("GUILockedSAS() returns 0x%x\n", result); 1480 return result; 1481 } 1482 1483 WARN("GUILockedSAS() failed (0x%x)\n", result); 1484 return WLX_SAS_ACTION_NONE; 1485 } 1486 1487 1488 static INT_PTR CALLBACK 1489 LockedDialogProc( 1490 IN HWND hwndDlg, 1491 IN UINT uMsg, 1492 IN WPARAM wParam, 1493 IN LPARAM lParam) 1494 { 1495 PDLG_DATA pDlgData; 1496 1497 pDlgData = (PDLG_DATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 1498 1499 switch (uMsg) 1500 { 1501 case WM_INITDIALOG: 1502 { 1503 pDlgData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DLG_DATA)); 1504 if (pDlgData == NULL) 1505 return FALSE; 1506 1507 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)pDlgData); 1508 1509 pDlgData->pgContext = (PGINA_CONTEXT)lParam; 1510 1511 /* Load the logo bitmap */ 1512 pDlgData->hBitmap = LoadImageW(pDlgData->pgContext->hDllInstance, MAKEINTRESOURCEW(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 1513 1514 SetWelcomeText(hwndDlg); 1515 1516 SetLockMessage(hwndDlg, IDC_LOCKED_MESSAGE, pDlgData->pgContext); 1517 return TRUE; 1518 } 1519 case WM_PAINT: 1520 { 1521 PAINTSTRUCT ps; 1522 if (pDlgData->hBitmap) 1523 { 1524 BeginPaint(hwndDlg, &ps); 1525 DrawStateW(ps.hdc, NULL, NULL, (LPARAM)pDlgData->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP); 1526 EndPaint(hwndDlg, &ps); 1527 } 1528 return TRUE; 1529 } 1530 case WM_DESTROY: 1531 { 1532 DeleteObject(pDlgData->hBitmap); 1533 HeapFree(GetProcessHeap(), 0, pDlgData); 1534 return TRUE; 1535 } 1536 } 1537 1538 return FALSE; 1539 } 1540 1541 1542 static VOID 1543 GUIDisplayLockedNotice( 1544 IN OUT PGINA_CONTEXT pgContext) 1545 { 1546 TRACE("GUIdisplayLockedNotice()\n"); 1547 1548 pgContext->pWlxFuncs->WlxDialogBoxParam( 1549 pgContext->hWlx, 1550 pgContext->hDllInstance, 1551 MAKEINTRESOURCEW(IDD_LOCKED), 1552 GetDesktopWindow(), 1553 LockedDialogProc, 1554 (LPARAM)pgContext); 1555 } 1556 1557 GINA_UI GinaGraphicalUI = { 1558 GUIInitialize, 1559 GUIDisplayStatusMessage, 1560 GUIRemoveStatusMessage, 1561 GUIDisplaySASNotice, 1562 GUILoggedOnSAS, 1563 GUILoggedOutSAS, 1564 GUILockedSAS, 1565 GUIDisplayLockedNotice, 1566 }; 1567