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