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 /* Open the Winlogon key */ 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 if (SubStatus == STATUS_ACCOUNT_EXPIRED) 936 { 937 ResourceMessageBox(pgContext, 938 hwndDlg, 939 MB_OK | MB_ICONEXCLAMATION, 940 IDS_LOGONTITLE, 941 IDS_ACCOUNTEXPIRED); 942 } 943 else 944 { 945 TRACE("Other error!\n"); 946 pgContext->pWlxFuncs->WlxMessageBox(pgContext->hWlx, 947 hwndDlg, 948 L"Other error!", 949 L"Logon error", 950 MB_OK | MB_ICONERROR); 951 goto done; 952 } 953 } 954 else if (!NT_SUCCESS(Status)) 955 { 956 TRACE("DoLoginTasks failed! Status 0x%08lx\n", Status); 957 goto done; 958 } 959 960 961 if (!CreateProfile(pgContext, UserName, Domain, Password)) 962 { 963 ERR("Failed to create the profile!\n"); 964 goto done; 965 } 966 967 ZeroMemory(pgContext->Password, sizeof(pgContext->Password)); 968 wcscpy(pgContext->Password, Password); 969 970 result = TRUE; 971 972 done: 973 pgContext->bAutoAdminLogon = FALSE; 974 975 if (UserName != NULL) 976 HeapFree(GetProcessHeap(), 0, UserName); 977 978 if (Password != NULL) 979 HeapFree(GetProcessHeap(), 0, Password); 980 981 if (Domain != NULL) 982 HeapFree(GetProcessHeap(), 0, Domain); 983 984 return result; 985 } 986 987 988 static 989 VOID 990 SetDomainComboBox( 991 HWND hwndDomainComboBox, 992 PGINA_CONTEXT pgContext) 993 { 994 WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1]; 995 DWORD dwComputerNameLength; 996 LONG lIndex = 0; 997 LONG lFindIndex; 998 999 SendMessageW(hwndDomainComboBox, CB_RESETCONTENT, 0, 0); 1000 1001 dwComputerNameLength = _countof(szComputerName); 1002 if (GetComputerNameW(szComputerName, &dwComputerNameLength)) 1003 { 1004 lIndex = SendMessageW(hwndDomainComboBox, CB_ADDSTRING, 0, (LPARAM)szComputerName); 1005 } 1006 1007 if (wcslen(pgContext->DomainName) != 0) 1008 { 1009 lFindIndex = SendMessageW(hwndDomainComboBox, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)pgContext->DomainName); 1010 if (lFindIndex == CB_ERR) 1011 { 1012 lIndex = SendMessageW(hwndDomainComboBox, CB_ADDSTRING, 0, (LPARAM)pgContext->DomainName); 1013 } 1014 else 1015 { 1016 lIndex = lFindIndex; 1017 } 1018 } 1019 1020 SendMessageW(hwndDomainComboBox, CB_SETCURSEL, lIndex, 0); 1021 } 1022 1023 1024 static INT_PTR CALLBACK 1025 LogonDialogProc( 1026 IN HWND hwndDlg, 1027 IN UINT uMsg, 1028 IN WPARAM wParam, 1029 IN LPARAM lParam) 1030 { 1031 PDLG_DATA pDlgData; 1032 1033 pDlgData = (PDLG_DATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 1034 1035 switch (uMsg) 1036 { 1037 case WM_INITDIALOG: 1038 { 1039 pDlgData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DLG_DATA)); 1040 if (pDlgData == NULL) 1041 return FALSE; 1042 1043 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)pDlgData); 1044 1045 /* FIXME: take care of NoDomainUI */ 1046 pDlgData->pgContext = (PGINA_CONTEXT)lParam; 1047 1048 /* Draw the logo bitmap */ 1049 pDlgData->hBitmap = LoadImageW(pDlgData->pgContext->hDllInstance, MAKEINTRESOURCEW(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 1050 1051 SetWelcomeText(hwndDlg); 1052 1053 if (pDlgData->pgContext->bAutoAdminLogon || 1054 !pDlgData->pgContext->bDontDisplayLastUserName) 1055 SetDlgItemTextW(hwndDlg, IDC_LOGON_USERNAME, pDlgData->pgContext->UserName); 1056 1057 if (pDlgData->pgContext->bAutoAdminLogon) 1058 SetDlgItemTextW(hwndDlg, IDC_LOGON_PASSWORD, pDlgData->pgContext->Password); 1059 1060 SetDomainComboBox(GetDlgItem(hwndDlg, IDC_LOGON_DOMAIN), pDlgData->pgContext); 1061 1062 if (pDlgData->pgContext->bDisableCAD) 1063 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE); 1064 1065 if (!pDlgData->pgContext->bShutdownWithoutLogon) 1066 EnableWindow(GetDlgItem(hwndDlg, IDC_LOGON_SHUTDOWN), FALSE); 1067 1068 SetFocus(GetDlgItem(hwndDlg, pDlgData->pgContext->bDontDisplayLastUserName ? IDC_LOGON_USERNAME : IDC_LOGON_PASSWORD)); 1069 1070 if (pDlgData->pgContext->bAutoAdminLogon) 1071 PostMessage(GetDlgItem(hwndDlg, IDOK), BM_CLICK, 0, 0); 1072 1073 return TRUE; 1074 } 1075 1076 case WM_PAINT: 1077 { 1078 PAINTSTRUCT ps; 1079 if (pDlgData->hBitmap) 1080 { 1081 BeginPaint(hwndDlg, &ps); 1082 DrawStateW(ps.hdc, NULL, NULL, (LPARAM)pDlgData->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP); 1083 EndPaint(hwndDlg, &ps); 1084 } 1085 return TRUE; 1086 } 1087 1088 case WM_DESTROY: 1089 DeleteObject(pDlgData->hBitmap); 1090 HeapFree(GetProcessHeap(), 0, pDlgData); 1091 return TRUE; 1092 1093 case WM_COMMAND: 1094 switch (LOWORD(wParam)) 1095 { 1096 case IDOK: 1097 if (DoLogon(hwndDlg, pDlgData->pgContext)) 1098 EndDialog(hwndDlg, WLX_SAS_ACTION_LOGON); 1099 return TRUE; 1100 1101 case IDCANCEL: 1102 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); 1103 return TRUE; 1104 1105 case IDC_LOGON_SHUTDOWN: 1106 if (OnShutDown(hwndDlg, pDlgData->pgContext) == IDOK) 1107 EndDialog(hwndDlg, pDlgData->pgContext->nShutdownAction); 1108 return TRUE; 1109 } 1110 break; 1111 } 1112 1113 return FALSE; 1114 } 1115 1116 1117 static 1118 INT_PTR 1119 CALLBACK 1120 LegalNoticeDialogProc( 1121 IN HWND hwndDlg, 1122 IN UINT uMsg, 1123 IN WPARAM wParam, 1124 IN LPARAM lParam) 1125 { 1126 PLEGALNOTICEDATA pLegalNotice; 1127 1128 switch (uMsg) 1129 { 1130 case WM_INITDIALOG: 1131 pLegalNotice = (PLEGALNOTICEDATA)lParam; 1132 SetWindowTextW(hwndDlg, pLegalNotice->pszCaption); 1133 SetDlgItemTextW(hwndDlg, IDC_LEGALNOTICE_TEXT, pLegalNotice->pszText); 1134 return TRUE; 1135 1136 case WM_COMMAND: 1137 switch (LOWORD(wParam)) 1138 { 1139 case IDOK: 1140 EndDialog(hwndDlg, 0); 1141 return TRUE; 1142 1143 case IDCANCEL: 1144 EndDialog(hwndDlg, 0); 1145 return TRUE; 1146 } 1147 break; 1148 } 1149 1150 return FALSE; 1151 } 1152 1153 1154 static INT 1155 GUILoggedOutSAS( 1156 IN OUT PGINA_CONTEXT pgContext) 1157 { 1158 LEGALNOTICEDATA LegalNotice = {NULL, NULL}; 1159 HKEY hKey = NULL; 1160 LONG rc; 1161 int result; 1162 1163 TRACE("GUILoggedOutSAS()\n"); 1164 1165 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1166 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 1167 0, 1168 KEY_QUERY_VALUE, 1169 &hKey); 1170 if (rc == ERROR_SUCCESS) 1171 { 1172 ReadRegSzValue(hKey, 1173 L"LegalNoticeCaption", 1174 &LegalNotice.pszCaption); 1175 1176 ReadRegSzValue(hKey, 1177 L"LegalNoticeText", 1178 &LegalNotice.pszText); 1179 1180 RegCloseKey(hKey); 1181 } 1182 1183 if (LegalNotice.pszCaption != NULL && wcslen(LegalNotice.pszCaption) != 0 && 1184 LegalNotice.pszText != NULL && wcslen(LegalNotice.pszText) != 0) 1185 { 1186 pgContext->pWlxFuncs->WlxDialogBoxParam(pgContext->hWlx, 1187 pgContext->hDllInstance, 1188 MAKEINTRESOURCEW(IDD_LEGALNOTICE), 1189 GetDesktopWindow(), 1190 LegalNoticeDialogProc, 1191 (LPARAM)&LegalNotice); 1192 } 1193 1194 if (LegalNotice.pszCaption != NULL) 1195 HeapFree(GetProcessHeap(), 0, LegalNotice.pszCaption); 1196 1197 if (LegalNotice.pszText != NULL) 1198 HeapFree(GetProcessHeap(), 0, LegalNotice.pszText); 1199 1200 result = pgContext->pWlxFuncs->WlxDialogBoxParam( 1201 pgContext->hWlx, 1202 pgContext->hDllInstance, 1203 MAKEINTRESOURCEW(IDD_LOGON), 1204 GetDesktopWindow(), 1205 LogonDialogProc, 1206 (LPARAM)pgContext); 1207 if (result >= WLX_SAS_ACTION_LOGON && 1208 result <= WLX_SAS_ACTION_SWITCH_CONSOLE) 1209 { 1210 WARN("WlxLoggedOutSAS() returns 0x%x\n", result); 1211 return result; 1212 } 1213 1214 WARN("WlxDialogBoxParam() failed (0x%x)\n", result); 1215 return WLX_SAS_ACTION_NONE; 1216 } 1217 1218 1219 static VOID 1220 SetLockMessage(HWND hwnd, 1221 INT nDlgItem, 1222 PGINA_CONTEXT pgContext) 1223 { 1224 WCHAR Buffer1[256]; 1225 WCHAR Buffer2[256]; 1226 WCHAR Buffer3[512]; 1227 1228 LoadStringW(pgContext->hDllInstance, IDS_LOCKMSG, Buffer1, _countof(Buffer1)); 1229 1230 wsprintfW(Buffer2, L"%s\\%s", pgContext->DomainName, pgContext->UserName); 1231 wsprintfW(Buffer3, Buffer1, Buffer2); 1232 1233 SetDlgItemTextW(hwnd, nDlgItem, Buffer3); 1234 } 1235 1236 1237 static 1238 BOOL 1239 DoUnlock( 1240 IN HWND hwndDlg, 1241 IN PGINA_CONTEXT pgContext, 1242 OUT LPINT Action) 1243 { 1244 WCHAR Buffer1[256]; 1245 WCHAR Buffer2[256]; 1246 LPWSTR UserName = NULL; 1247 LPWSTR Password = NULL; 1248 BOOL res = FALSE; 1249 1250 if (GetTextboxText(hwndDlg, IDC_UNLOCK_USERNAME, &UserName) && *UserName == '\0') 1251 { 1252 HeapFree(GetProcessHeap(), 0, UserName); 1253 return FALSE; 1254 } 1255 1256 if (GetTextboxText(hwndDlg, IDC_UNLOCK_PASSWORD, &Password)) 1257 { 1258 if (UserName != NULL && Password != NULL && 1259 wcscmp(UserName, pgContext->UserName) == 0 && 1260 wcscmp(Password, pgContext->Password) == 0) 1261 { 1262 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA; 1263 res = TRUE; 1264 } 1265 else if (wcscmp(UserName, pgContext->UserName) == 0 && 1266 wcscmp(Password, pgContext->Password) != 0) 1267 { 1268 /* Wrong Password */ 1269 LoadStringW(pgContext->hDllInstance, IDS_LOCKEDWRONGPASSWORD, Buffer2, _countof(Buffer2)); 1270 LoadStringW(pgContext->hDllInstance, IDS_COMPUTERLOCKED, Buffer1, _countof(Buffer1)); 1271 MessageBoxW(hwndDlg, Buffer2, Buffer1, MB_OK | MB_ICONERROR); 1272 } 1273 else 1274 { 1275 /* Wrong user name */ 1276 if (DoAdminUnlock(pgContext, UserName, NULL, Password)) 1277 { 1278 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA; 1279 res = TRUE; 1280 } 1281 else 1282 { 1283 LoadStringW(pgContext->hDllInstance, IDS_LOCKEDWRONGUSER, Buffer1, _countof(Buffer1)); 1284 wsprintfW(Buffer2, Buffer1, pgContext->DomainName, pgContext->UserName); 1285 LoadStringW(pgContext->hDllInstance, IDS_COMPUTERLOCKED, Buffer1, _countof(Buffer1)); 1286 MessageBoxW(hwndDlg, Buffer2, Buffer1, MB_OK | MB_ICONERROR); 1287 } 1288 } 1289 } 1290 1291 if (UserName != NULL) 1292 HeapFree(GetProcessHeap(), 0, UserName); 1293 1294 if (Password != NULL) 1295 HeapFree(GetProcessHeap(), 0, Password); 1296 1297 return res; 1298 } 1299 1300 1301 static 1302 INT_PTR 1303 CALLBACK 1304 UnlockDialogProc( 1305 IN HWND hwndDlg, 1306 IN UINT uMsg, 1307 IN WPARAM wParam, 1308 IN LPARAM lParam) 1309 { 1310 PDLG_DATA pDlgData; 1311 INT result = WLX_SAS_ACTION_NONE; 1312 1313 pDlgData = (PDLG_DATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 1314 1315 switch (uMsg) 1316 { 1317 case WM_INITDIALOG: 1318 { 1319 pDlgData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DLG_DATA)); 1320 if (pDlgData == NULL) 1321 return FALSE; 1322 1323 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)pDlgData); 1324 1325 pDlgData->pgContext = (PGINA_CONTEXT)lParam; 1326 1327 SetWelcomeText(hwndDlg); 1328 1329 SetLockMessage(hwndDlg, IDC_UNLOCK_MESSAGE, pDlgData->pgContext); 1330 1331 SetDlgItemTextW(hwndDlg, IDC_UNLOCK_USERNAME, pDlgData->pgContext->UserName); 1332 SetFocus(GetDlgItem(hwndDlg, IDC_UNLOCK_PASSWORD)); 1333 1334 if (pDlgData->pgContext->bDisableCAD) 1335 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE); 1336 1337 /* Load the logo bitmap */ 1338 pDlgData->hBitmap = LoadImageW(pDlgData->pgContext->hDllInstance, MAKEINTRESOURCEW(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 1339 return TRUE; 1340 } 1341 1342 case WM_PAINT: 1343 { 1344 PAINTSTRUCT ps; 1345 if (pDlgData->hBitmap) 1346 { 1347 BeginPaint(hwndDlg, &ps); 1348 DrawStateW(ps.hdc, NULL, NULL, (LPARAM)pDlgData->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP); 1349 EndPaint(hwndDlg, &ps); 1350 } 1351 return TRUE; 1352 } 1353 case WM_DESTROY: 1354 DeleteObject(pDlgData->hBitmap); 1355 HeapFree(GetProcessHeap(), 0, pDlgData); 1356 return TRUE; 1357 1358 case WM_COMMAND: 1359 switch (LOWORD(wParam)) 1360 { 1361 case IDOK: 1362 if (DoUnlock(hwndDlg, pDlgData->pgContext, &result)) 1363 EndDialog(hwndDlg, result); 1364 return TRUE; 1365 1366 case IDCANCEL: 1367 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); 1368 return TRUE; 1369 } 1370 break; 1371 } 1372 1373 return FALSE; 1374 } 1375 1376 1377 static INT 1378 GUILockedSAS( 1379 IN OUT PGINA_CONTEXT pgContext) 1380 { 1381 int result; 1382 1383 TRACE("GUILockedSAS()\n"); 1384 1385 result = pgContext->pWlxFuncs->WlxDialogBoxParam( 1386 pgContext->hWlx, 1387 pgContext->hDllInstance, 1388 MAKEINTRESOURCEW(IDD_UNLOCK), 1389 GetDesktopWindow(), 1390 UnlockDialogProc, 1391 (LPARAM)pgContext); 1392 if (result >= WLX_SAS_ACTION_LOGON && 1393 result <= WLX_SAS_ACTION_SWITCH_CONSOLE) 1394 { 1395 WARN("GUILockedSAS() returns 0x%x\n", result); 1396 return result; 1397 } 1398 1399 WARN("GUILockedSAS() failed (0x%x)\n", result); 1400 return WLX_SAS_ACTION_NONE; 1401 } 1402 1403 1404 static INT_PTR CALLBACK 1405 LockedDialogProc( 1406 IN HWND hwndDlg, 1407 IN UINT uMsg, 1408 IN WPARAM wParam, 1409 IN LPARAM lParam) 1410 { 1411 PDLG_DATA pDlgData; 1412 1413 pDlgData = (PDLG_DATA)GetWindowLongPtrW(hwndDlg, GWLP_USERDATA); 1414 1415 switch (uMsg) 1416 { 1417 case WM_INITDIALOG: 1418 { 1419 pDlgData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DLG_DATA)); 1420 if (pDlgData == NULL) 1421 return FALSE; 1422 1423 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)pDlgData); 1424 1425 pDlgData->pgContext = (PGINA_CONTEXT)lParam; 1426 1427 /* Load the logo bitmap */ 1428 pDlgData->hBitmap = LoadImageW(pDlgData->pgContext->hDllInstance, MAKEINTRESOURCEW(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); 1429 1430 SetWelcomeText(hwndDlg); 1431 1432 SetLockMessage(hwndDlg, IDC_LOCKED_MESSAGE, pDlgData->pgContext); 1433 return TRUE; 1434 } 1435 case WM_PAINT: 1436 { 1437 PAINTSTRUCT ps; 1438 if (pDlgData->hBitmap) 1439 { 1440 BeginPaint(hwndDlg, &ps); 1441 DrawStateW(ps.hdc, NULL, NULL, (LPARAM)pDlgData->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP); 1442 EndPaint(hwndDlg, &ps); 1443 } 1444 return TRUE; 1445 } 1446 case WM_DESTROY: 1447 { 1448 DeleteObject(pDlgData->hBitmap); 1449 HeapFree(GetProcessHeap(), 0, pDlgData); 1450 return TRUE; 1451 } 1452 } 1453 1454 return FALSE; 1455 } 1456 1457 1458 static VOID 1459 GUIDisplayLockedNotice( 1460 IN OUT PGINA_CONTEXT pgContext) 1461 { 1462 TRACE("GUIdisplayLockedNotice()\n"); 1463 1464 pgContext->pWlxFuncs->WlxDialogBoxParam( 1465 pgContext->hWlx, 1466 pgContext->hDllInstance, 1467 MAKEINTRESOURCEW(IDD_LOCKED), 1468 GetDesktopWindow(), 1469 LockedDialogProc, 1470 (LPARAM)pgContext); 1471 } 1472 1473 GINA_UI GinaGraphicalUI = { 1474 GUIInitialize, 1475 GUIDisplayStatusMessage, 1476 GUIRemoveStatusMessage, 1477 GUIDisplaySASNotice, 1478 GUILoggedOnSAS, 1479 GUILoggedOutSAS, 1480 GUILockedSAS, 1481 GUIDisplayLockedNotice, 1482 }; 1483