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