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