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