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