1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Winlogon 4 * FILE: base/system/winlogon/wlx.c 5 * PURPOSE: Logon 6 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net) 7 * Ge van Geldorp (gvg@reactos.com) 8 * Herv� Poussineau (hpoussin@reactos.org) 9 */ 10 11 /* INCLUDES *****************************************************************/ 12 13 #include "winlogon.h" 14 15 #define DESKTOP_ALL (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | \ 16 DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | \ 17 DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \ 18 DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED) 19 20 #define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | \ 21 WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | \ 22 WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | \ 23 WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | WINSTA_READSCREEN | \ 24 STANDARD_RIGHTS_REQUIRED) 25 26 #define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | \ 27 GENERIC_EXECUTE | GENERIC_ALL) 28 29 typedef struct _DIALOG_LIST_ENTRY 30 { 31 LIST_ENTRY Entry; 32 HWND hWnd; 33 DLGPROC DlgProc; 34 LPARAM lParam; 35 } DIALOG_LIST_ENTRY, *PDIALOG_LIST_ENTRY; 36 37 /* GLOBALS ******************************************************************/ 38 39 //static UINT_PTR IdTimer; 40 static LIST_ENTRY DialogListHead; 41 42 /* FUNCTIONS ****************************************************************/ 43 44 VOID 45 InitDialogListHead(VOID) 46 { 47 InitializeListHead(&DialogListHead); 48 } 49 50 51 static 52 PDIALOG_LIST_ENTRY 53 AddDialogListEntry(VOID) 54 { 55 PDIALOG_LIST_ENTRY ListEntry; 56 57 ListEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DIALOG_LIST_ENTRY)); 58 if (ListEntry == NULL) 59 return NULL; 60 61 TRACE("Add entry %p\n", ListEntry); 62 63 InsertHeadList(&DialogListHead, 64 &ListEntry->Entry); 65 66 return ListEntry; 67 } 68 69 70 static 71 VOID 72 RemoveDialogListEntry(PDIALOG_LIST_ENTRY ListEntry) 73 { 74 TRACE("Remove entry %p\n", ListEntry); 75 76 RemoveEntryList(&ListEntry->Entry); 77 RtlFreeHeap(RtlGetProcessHeap(), 0, ListEntry); 78 } 79 80 81 static 82 PDIALOG_LIST_ENTRY 83 GetDialogListEntry(HWND hwndDlg) 84 { 85 PDIALOG_LIST_ENTRY Current; 86 PLIST_ENTRY ListEntry; 87 88 ListEntry = DialogListHead.Flink; 89 while (ListEntry != &DialogListHead) 90 { 91 Current = CONTAINING_RECORD(ListEntry, 92 DIALOG_LIST_ENTRY, 93 Entry); 94 if (Current->hWnd == hwndDlg) 95 { 96 TRACE("Found entry: %p\n", Current); 97 return Current; 98 } 99 100 ListEntry = ListEntry->Flink; 101 } 102 103 TRACE("Found no entry!\n"); 104 return NULL; 105 } 106 107 108 HWND 109 GetTopDialogWindow(VOID) 110 { 111 PDIALOG_LIST_ENTRY Current; 112 PLIST_ENTRY ListEntry; 113 114 ListEntry = DialogListHead.Flink; 115 if (ListEntry != &DialogListHead) 116 { 117 Current = CONTAINING_RECORD(ListEntry, 118 DIALOG_LIST_ENTRY, 119 Entry); 120 121 TRACE("Found entry: %p window %p\n", Current, Current->hWnd); 122 return Current->hWnd; 123 } 124 125 TRACE("Found no window\n"); 126 return NULL; 127 } 128 129 130 static 131 INT_PTR 132 CALLBACK 133 DefaultWlxWindowProc( 134 IN HWND hwndDlg, 135 IN UINT uMsg, 136 IN WPARAM wParam, 137 IN LPARAM lParam) 138 { 139 PDIALOG_LIST_ENTRY ListEntry; 140 INT_PTR ret; 141 142 if (uMsg == WM_INITDIALOG) 143 { 144 ListEntry = (PDIALOG_LIST_ENTRY)lParam; 145 146 TRACE("Set dialog handle: %p\n", hwndDlg); 147 ListEntry->hWnd = hwndDlg; 148 lParam = ListEntry->lParam; 149 // SetTopTimeout(hWnd); 150 } 151 else 152 { 153 ListEntry = GetDialogListEntry(hwndDlg); 154 if (ListEntry == NULL) 155 return FALSE; 156 } 157 158 if (uMsg == WLX_WM_SAS) 159 { 160 EndDialog(hwndDlg, WLX_DLG_SAS); 161 return 0; 162 } 163 164 ret = ListEntry->DlgProc(hwndDlg, uMsg, wParam, lParam); 165 166 return ret; 167 168 /* 169 if (uMsg == WM_TIMER && (UINT_PTR)wParam == IdTimer) 170 { 171 EndDialog(hwndDlg, -1); 172 KillTimer(hwndDlg, IdTimer); 173 return TRUE; 174 } 175 else if (uMsg == WM_INITDIALOG) 176 { 177 IdTimer = SetTimer(hwndDlg, 0, WLSession->DialogTimeout * 1000, NULL); 178 return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam); 179 } 180 else if (uMsg == WM_NCDESTROY) 181 { 182 BOOL ret; 183 ret = PreviousWindowProc(hwndDlg, uMsg, wParam, lParam); 184 PreviousWindowProc = NULL; 185 return ret; 186 } 187 else 188 { 189 return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam); 190 } 191 */ 192 } 193 194 /* 195 * @implemented 196 */ 197 VOID 198 WINAPI 199 WlxUseCtrlAltDel( 200 HANDLE hWlx) 201 { 202 ULONG_PTR OldValue; 203 204 TRACE("WlxUseCtrlAltDel()\n"); 205 206 WlxSetOption(hWlx, WLX_OPTION_USE_CTRL_ALT_DEL, TRUE, &OldValue); 207 } 208 209 /* 210 * @implemented 211 */ 212 VOID 213 WINAPI 214 WlxSetContextPointer( 215 HANDLE hWlx, 216 PVOID pWlxContext) 217 { 218 ULONG_PTR OldValue; 219 220 TRACE("WlxSetContextPointer(%p)\n", pWlxContext); 221 222 WlxSetOption(hWlx, WLX_OPTION_CONTEXT_POINTER, (ULONG_PTR)pWlxContext, &OldValue); 223 } 224 225 /* 226 * @implemented 227 */ 228 VOID 229 WINAPI 230 WlxSasNotify( 231 HANDLE hWlx, 232 DWORD dwSasType) 233 { 234 PWLSESSION Session = (PWLSESSION)hWlx; 235 236 TRACE("WlxSasNotify(0x%lx)\n", dwSasType); 237 238 if (dwSasType == WLX_SAS_TYPE_CTRL_ALT_DEL || dwSasType > WLX_SAS_TYPE_MAX_MSFT_VALUE) 239 PostMessageW(Session->SASWindow, WLX_WM_SAS, dwSasType, 0); 240 } 241 242 /* 243 * @implemented 244 */ 245 BOOL 246 WINAPI 247 WlxSetTimeout( 248 HANDLE hWlx, 249 DWORD Timeout) 250 { 251 PWLSESSION Session = (PWLSESSION)hWlx; 252 253 TRACE("WlxSetTimeout(%lu)\n", Timeout); 254 255 Session->DialogTimeout = Timeout; 256 return TRUE; 257 } 258 259 /* 260 * @unimplemented 261 */ 262 int 263 WINAPI 264 WlxAssignShellProtection( 265 HANDLE hWlx, 266 HANDLE hToken, 267 HANDLE hProcess, 268 HANDLE hThread) 269 { 270 UNREFERENCED_PARAMETER(hWlx); 271 UNREFERENCED_PARAMETER(hToken); 272 UNREFERENCED_PARAMETER(hProcess); 273 UNREFERENCED_PARAMETER(hThread); 274 275 UNIMPLEMENTED; 276 return 0; 277 } 278 279 /* 280 * @implemented 281 */ 282 int 283 WINAPI 284 WlxMessageBox( 285 HANDLE hWlx, 286 HWND hwndOwner, 287 LPWSTR lpszText, 288 LPWSTR lpszTitle, 289 UINT fuStyle) 290 { 291 UNREFERENCED_PARAMETER(hWlx); 292 293 TRACE("WlxMessageBox()\n"); 294 /* FIXME: Provide a custom window proc to be able to handle timeout */ 295 return MessageBoxW(hwndOwner, lpszText, lpszTitle, fuStyle); 296 } 297 298 /* 299 * @implemented 300 */ 301 int 302 WINAPI 303 WlxDialogBox( 304 HANDLE hWlx, 305 HANDLE hInst, 306 LPWSTR lpszTemplate, 307 HWND hwndOwner, 308 DLGPROC dlgprc) 309 { 310 UNREFERENCED_PARAMETER(hWlx); 311 312 TRACE("WlxDialogBox()\n"); 313 314 return (int)WlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner, dlgprc, 0); 315 } 316 317 /* 318 * @implemented 319 */ 320 int 321 WINAPI 322 WlxDialogBoxParam( 323 HANDLE hWlx, 324 HANDLE hInst, 325 LPWSTR lpszTemplate, 326 HWND hwndOwner, 327 DLGPROC dlgprc, 328 LPARAM dwInitParam) 329 { 330 PDIALOG_LIST_ENTRY ListEntry; 331 int ret; 332 333 UNREFERENCED_PARAMETER(hWlx); 334 335 TRACE("WlxDialogBoxParam()\n"); 336 337 ListEntry = AddDialogListEntry(); 338 if (ListEntry == NULL) 339 return -1; 340 341 ListEntry->DlgProc = dlgprc; 342 ListEntry->lParam = dwInitParam; 343 344 ret = (int)DialogBoxParamW(hInst, lpszTemplate, hwndOwner, DefaultWlxWindowProc, (LPARAM)ListEntry); 345 346 RemoveDialogListEntry(ListEntry); 347 348 return ret; 349 } 350 351 /* 352 * @implemented 353 */ 354 int 355 WINAPI 356 WlxDialogBoxIndirect( 357 HANDLE hWlx, 358 HANDLE hInst, 359 LPCDLGTEMPLATE hDialogTemplate, 360 HWND hwndOwner, 361 DLGPROC dlgprc) 362 { 363 UNREFERENCED_PARAMETER(hWlx); 364 365 TRACE("WlxDialogBoxIndirect()\n"); 366 367 return (int)WlxDialogBoxIndirectParam(hWlx, hInst, hDialogTemplate, hwndOwner, dlgprc, 0); 368 } 369 370 /* 371 * @implemented 372 */ 373 int 374 WINAPI 375 WlxDialogBoxIndirectParam( 376 HANDLE hWlx, 377 HANDLE hInst, 378 LPCDLGTEMPLATE hDialogTemplate, 379 HWND hwndOwner, 380 DLGPROC dlgprc, 381 LPARAM dwInitParam) 382 { 383 PDIALOG_LIST_ENTRY ListEntry; 384 int ret; 385 386 UNREFERENCED_PARAMETER(hWlx); 387 388 TRACE("WlxDialogBoxIndirectParam()\n"); 389 390 ListEntry = AddDialogListEntry(); 391 if (ListEntry == NULL) 392 return -1; 393 394 ListEntry->DlgProc = dlgprc; 395 ListEntry->lParam = dwInitParam; 396 397 ret = (int)DialogBoxIndirectParamW(hInst, hDialogTemplate, hwndOwner, DefaultWlxWindowProc, (LPARAM)ListEntry); 398 399 RemoveDialogListEntry(ListEntry); 400 401 return ret; 402 } 403 404 /* 405 * @implemented 406 */ 407 int 408 WINAPI 409 WlxSwitchDesktopToUser( 410 HANDLE hWlx) 411 { 412 PWLSESSION Session = (PWLSESSION)hWlx; 413 414 TRACE("WlxSwitchDesktopToUser()\n"); 415 416 return (int)SwitchDesktop(Session->ApplicationDesktop); 417 } 418 419 /* 420 * @implemented 421 */ 422 int 423 WINAPI 424 WlxSwitchDesktopToWinlogon( 425 HANDLE hWlx) 426 { 427 PWLSESSION Session = (PWLSESSION)hWlx; 428 429 TRACE("WlxSwitchDesktopToWinlogon()\n"); 430 431 return (int)SwitchDesktop(Session->WinlogonDesktop); 432 } 433 434 /* 435 * @unimplemented 436 */ 437 int 438 WINAPI 439 WlxChangePasswordNotify( 440 HANDLE hWlx, 441 PWLX_MPR_NOTIFY_INFO pMprInfo, 442 DWORD dwChangeInfo) 443 { 444 UNREFERENCED_PARAMETER(hWlx); 445 UNREFERENCED_PARAMETER(pMprInfo); 446 UNREFERENCED_PARAMETER(dwChangeInfo); 447 448 UNIMPLEMENTED; 449 return 0; 450 } 451 452 /* 453 * @unimplemented 454 */ 455 BOOL 456 WINAPI 457 WlxGetSourceDesktop( 458 HANDLE hWlx, 459 PWLX_DESKTOP* ppDesktop) 460 { 461 UNREFERENCED_PARAMETER(hWlx); 462 UNREFERENCED_PARAMETER(ppDesktop); 463 464 UNIMPLEMENTED; 465 return FALSE; 466 } 467 468 /* 469 * @unimplemented 470 */ 471 BOOL 472 WINAPI 473 WlxSetReturnDesktop( 474 HANDLE hWlx, 475 PWLX_DESKTOP pDesktop) 476 { 477 UNREFERENCED_PARAMETER(hWlx); 478 UNREFERENCED_PARAMETER(pDesktop); 479 480 UNIMPLEMENTED; 481 return FALSE; 482 } 483 484 /* 485 * @unimplemented 486 */ 487 BOOL 488 WINAPI 489 WlxCreateUserDesktop( 490 HANDLE hWlx, 491 HANDLE hToken, 492 DWORD Flags, 493 PWSTR pszDesktopName, 494 PWLX_DESKTOP* ppDesktop) 495 { 496 UNREFERENCED_PARAMETER(hWlx); 497 UNREFERENCED_PARAMETER(hToken); 498 UNREFERENCED_PARAMETER(Flags); 499 UNREFERENCED_PARAMETER(pszDesktopName); 500 UNREFERENCED_PARAMETER(ppDesktop); 501 502 UNIMPLEMENTED; 503 return FALSE; 504 } 505 506 /* 507 * @unimplemented 508 */ 509 int 510 WINAPI 511 WlxChangePasswordNotifyEx( 512 HANDLE hWlx, 513 PWLX_MPR_NOTIFY_INFO pMprInfo, 514 DWORD dwChangeInfo, 515 PWSTR ProviderName, 516 PVOID Reserved) 517 { 518 UNREFERENCED_PARAMETER(hWlx); 519 UNREFERENCED_PARAMETER(pMprInfo); 520 UNREFERENCED_PARAMETER(dwChangeInfo); 521 UNREFERENCED_PARAMETER(ProviderName); 522 UNREFERENCED_PARAMETER(Reserved); 523 524 UNIMPLEMENTED; 525 return 0; 526 } 527 528 /* 529 * @unimplemented 530 */ 531 BOOL 532 WINAPI 533 WlxCloseUserDesktop( 534 HANDLE hWlx, 535 PWLX_DESKTOP pDesktop, 536 HANDLE hToken) 537 { 538 UNREFERENCED_PARAMETER(hWlx); 539 UNREFERENCED_PARAMETER(pDesktop); 540 UNREFERENCED_PARAMETER(hToken); 541 542 UNIMPLEMENTED; 543 return FALSE; 544 } 545 546 /* 547 * @implemented 548 */ 549 BOOL 550 WINAPI 551 WlxSetOption( 552 HANDLE hWlx, 553 DWORD Option, 554 ULONG_PTR Value, 555 ULONG_PTR* OldValue) 556 { 557 PWLSESSION Session = (PWLSESSION)hWlx; 558 559 TRACE("WlxSetOption(%lu)\n", Option); 560 561 switch (Option) 562 { 563 case WLX_OPTION_USE_CTRL_ALT_DEL: 564 *OldValue = (ULONG_PTR)Session->Gina.UseCtrlAltDelete; 565 Session->Gina.UseCtrlAltDelete = (BOOL)Value; 566 return TRUE; 567 case WLX_OPTION_CONTEXT_POINTER: 568 *OldValue = (ULONG_PTR)Session->Gina.Context; 569 Session->Gina.Context = (PVOID)Value; 570 return TRUE; 571 case WLX_OPTION_USE_SMART_CARD: 572 UNIMPLEMENTED; 573 return FALSE; 574 } 575 576 return FALSE; 577 } 578 579 /* 580 * @implemented 581 */ 582 BOOL 583 WINAPI 584 WlxGetOption( 585 HANDLE hWlx, 586 DWORD Option, 587 ULONG_PTR* Value) 588 { 589 PWLSESSION Session = (PWLSESSION)hWlx; 590 591 TRACE("WlxGetOption(%lu)\n", Option); 592 593 switch (Option) 594 { 595 case WLX_OPTION_USE_CTRL_ALT_DEL: 596 *Value = (ULONG_PTR)Session->Gina.UseCtrlAltDelete; 597 return TRUE; 598 case WLX_OPTION_CONTEXT_POINTER: 599 { 600 *Value = (ULONG_PTR)Session->Gina.Context; 601 return TRUE; 602 } 603 case WLX_OPTION_USE_SMART_CARD: 604 case WLX_OPTION_SMART_CARD_PRESENT: 605 case WLX_OPTION_SMART_CARD_INFO: 606 UNIMPLEMENTED; 607 return FALSE; 608 case WLX_OPTION_DISPATCH_TABLE_SIZE: 609 { 610 switch (Session->Gina.Version) 611 { 612 case WLX_VERSION_1_0: 613 *Value = sizeof(WLX_DISPATCH_VERSION_1_0); 614 break; 615 case WLX_VERSION_1_1: 616 *Value = sizeof(WLX_DISPATCH_VERSION_1_1); 617 break; 618 case WLX_VERSION_1_2: 619 *Value = sizeof(WLX_DISPATCH_VERSION_1_2); 620 break; 621 case WLX_VERSION_1_3: 622 *Value = sizeof(WLX_DISPATCH_VERSION_1_3); 623 break; 624 case WLX_VERSION_1_4: 625 *Value = sizeof(WLX_DISPATCH_VERSION_1_4); 626 break; 627 default: 628 return FALSE; 629 } 630 return TRUE; 631 } 632 } 633 634 return FALSE; 635 } 636 637 /* 638 * @unimplemented 639 */ 640 VOID 641 WINAPI 642 WlxWin31Migrate( 643 HANDLE hWlx) 644 { 645 UNREFERENCED_PARAMETER(hWlx); 646 647 UNIMPLEMENTED; 648 } 649 650 /* 651 * @unimplemented 652 */ 653 BOOL 654 WINAPI 655 WlxQueryClientCredentials( 656 PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred) 657 { 658 UNREFERENCED_PARAMETER(pCred); 659 660 UNIMPLEMENTED; 661 return FALSE; 662 } 663 664 /* 665 * @unimplemented 666 */ 667 BOOL 668 WINAPI 669 WlxQueryInetConnectorCredentials( 670 PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred) 671 { 672 UNREFERENCED_PARAMETER(pCred); 673 674 UNIMPLEMENTED; 675 return FALSE; 676 } 677 678 /* 679 * @unimplemented 680 */ 681 BOOL 682 WINAPI 683 WlxDisconnect(VOID) 684 { 685 UNIMPLEMENTED; 686 return FALSE; 687 } 688 689 /* 690 * @unimplemented 691 */ 692 DWORD 693 WINAPI 694 WlxQueryTerminalServicesData( 695 HANDLE hWlx, 696 PWLX_TERMINAL_SERVICES_DATA pTSData, 697 WCHAR* UserName, 698 WCHAR* Domain) 699 { 700 UNREFERENCED_PARAMETER(hWlx); 701 UNREFERENCED_PARAMETER(pTSData); 702 UNREFERENCED_PARAMETER(UserName); 703 UNREFERENCED_PARAMETER(Domain); 704 705 UNIMPLEMENTED; 706 return 0; 707 } 708 709 /* 710 * @unimplemented 711 */ 712 DWORD 713 WINAPI 714 WlxQueryConsoleSwitchCredentials( 715 PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred) 716 { 717 UNREFERENCED_PARAMETER(pCred); 718 719 UNIMPLEMENTED; 720 return 0; 721 } 722 723 /* 724 * @unimplemented 725 */ 726 BOOL 727 WINAPI 728 WlxQueryTsLogonCredentials( 729 PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred) 730 { 731 UNREFERENCED_PARAMETER(pCred); 732 733 UNIMPLEMENTED; 734 return FALSE; 735 } 736 737 static 738 WLX_DISPATCH_VERSION_1_4 FunctionTable = { 739 WlxUseCtrlAltDel, 740 WlxSetContextPointer, 741 WlxSasNotify, 742 WlxSetTimeout, 743 WlxAssignShellProtection, 744 WlxMessageBox, 745 WlxDialogBox, 746 WlxDialogBoxParam, 747 WlxDialogBoxIndirect, 748 WlxDialogBoxIndirectParam, 749 WlxSwitchDesktopToUser, 750 WlxSwitchDesktopToWinlogon, 751 WlxChangePasswordNotify, 752 WlxGetSourceDesktop, 753 WlxSetReturnDesktop, 754 WlxCreateUserDesktop, 755 WlxChangePasswordNotifyEx, 756 WlxCloseUserDesktop, 757 WlxSetOption, 758 WlxGetOption, 759 WlxWin31Migrate, 760 WlxQueryClientCredentials, 761 WlxQueryInetConnectorCredentials, 762 WlxDisconnect, 763 WlxQueryTerminalServicesData, 764 WlxQueryConsoleSwitchCredentials, 765 WlxQueryTsLogonCredentials 766 }; 767 768 /******************************************************************************/ 769 770 static 771 BOOL 772 GetGinaPath( 773 OUT LPWSTR Path, 774 IN DWORD Len) 775 { 776 LONG Status; 777 DWORD Type, Size; 778 HKEY hKey; 779 780 Status = RegOpenKeyExW( 781 HKEY_LOCAL_MACHINE, 782 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 783 0, 784 KEY_QUERY_VALUE, 785 &hKey); 786 if (Status != ERROR_SUCCESS) 787 { 788 /* Default value */ 789 wcsncpy(Path, L"msgina.dll", Len); 790 return TRUE; 791 } 792 793 Size = Len * sizeof(WCHAR); 794 Status = RegQueryValueExW( 795 hKey, 796 L"GinaDLL", 797 NULL, 798 &Type, 799 (LPBYTE)Path, 800 &Size); 801 if (Status != ERROR_SUCCESS || Type != REG_SZ || Size == 0) 802 wcsncpy(Path, L"msgina.dll", Len); 803 RegCloseKey(hKey); 804 return TRUE; 805 } 806 807 static 808 BOOL 809 WINAPI 810 DefaultWlxScreenSaverNotify( 811 IN PVOID pWlxContext, 812 IN OUT BOOL *pSecure) 813 { 814 if (*pSecure) 815 *pSecure = WLSession->Gina.Functions.WlxIsLogoffOk(pWlxContext); 816 return TRUE; 817 } 818 819 static 820 BOOL 821 LoadGina( 822 IN OUT PGINAFUNCTIONS Functions, 823 OUT DWORD *DllVersion, 824 OUT HMODULE *GinaInstance) 825 { 826 HMODULE hGina = NULL; 827 WCHAR GinaDll[MAX_PATH + 1]; 828 BOOL ret = FALSE; 829 830 GinaDll[0] = '\0'; 831 if (!GetGinaPath(GinaDll, MAX_PATH)) 832 goto cleanup; 833 /* Terminate string */ 834 GinaDll[MAX_PATH] = '\0'; 835 836 hGina = LoadLibraryW(GinaDll); 837 if (!hGina) 838 goto cleanup; 839 840 Functions->WlxNegotiate = (PFWLXNEGOTIATE)GetProcAddress(hGina, "WlxNegotiate"); 841 Functions->WlxInitialize = (PFWLXINITIALIZE)GetProcAddress(hGina, "WlxInitialize"); 842 843 if (!Functions->WlxInitialize) 844 goto cleanup; 845 846 if (!Functions->WlxNegotiate) 847 { 848 /* Assume current version */ 849 *DllVersion = WLX_CURRENT_VERSION; 850 } 851 else 852 { 853 TRACE("About to negotiate with Gina %S. Winlogon uses version %x\n", 854 GinaDll, WLX_CURRENT_VERSION); 855 if (!Functions->WlxNegotiate(WLX_CURRENT_VERSION, DllVersion)) 856 goto cleanup; 857 } 858 859 TRACE("Gina uses WLX_VERSION %lx\n", *DllVersion); 860 861 if (*DllVersion >= WLX_VERSION_1_0) 862 { 863 Functions->WlxActivateUserShell = (PFWLXACTIVATEUSERSHELL)GetProcAddress(hGina, "WlxActivateUserShell"); 864 if (!Functions->WlxActivateUserShell) goto cleanup; 865 Functions->WlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hGina, "WlxDisplayLockedNotice"); 866 if (!Functions->WlxDisplayLockedNotice) goto cleanup; 867 Functions->WlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE)GetProcAddress(hGina, "WlxDisplaySASNotice"); 868 if (!Functions->WlxDisplaySASNotice) goto cleanup; 869 Functions->WlxIsLockOk = (PFWLXISLOCKOK)GetProcAddress(hGina, "WlxIsLockOk"); 870 if (!Functions->WlxIsLockOk) goto cleanup; 871 Functions->WlxIsLogoffOk = (PFWLXISLOGOFFOK)GetProcAddress(hGina, "WlxIsLogoffOk"); 872 if (!Functions->WlxIsLogoffOk) goto cleanup; 873 Functions->WlxLoggedOnSAS = (PFWLXLOGGEDONSAS)GetProcAddress(hGina, "WlxLoggedOnSAS"); 874 if (!Functions->WlxLoggedOnSAS) goto cleanup; 875 Functions->WlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS)GetProcAddress(hGina, "WlxLoggedOutSAS"); 876 if (!Functions->WlxLoggedOutSAS) goto cleanup; 877 Functions->WlxLogoff = (PFWLXLOGOFF)GetProcAddress(hGina, "WlxLogoff"); 878 if (!Functions->WlxLogoff) goto cleanup; 879 Functions->WlxShutdown = (PFWLXSHUTDOWN)GetProcAddress(hGina, "WlxShutdown"); 880 if (!Functions->WlxShutdown) goto cleanup; 881 Functions->WlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS)GetProcAddress(hGina, "WlxWkstaLockedSAS"); 882 if (!Functions->WlxWkstaLockedSAS) goto cleanup; 883 } 884 885 if (*DllVersion >= WLX_VERSION_1_1) 886 { 887 Functions->WlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY)GetProcAddress(hGina, "WlxScreenSaverNotify"); 888 Functions->WlxStartApplication = (PFWLXSTARTAPPLICATION)GetProcAddress(hGina, "WlxStartApplication"); 889 } 890 891 if (*DllVersion >= WLX_VERSION_1_3) 892 { 893 Functions->WlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE)GetProcAddress(hGina, "WlxDisplayStatusMessage"); 894 if (!Functions->WlxDisplayStatusMessage) goto cleanup; 895 Functions->WlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE)GetProcAddress(hGina, "WlxGetStatusMessage"); 896 if (!Functions->WlxGetStatusMessage) goto cleanup; 897 Functions->WlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD)GetProcAddress(hGina, "WlxNetworkProviderLoad"); 898 if (!Functions->WlxNetworkProviderLoad) goto cleanup; 899 Functions->WlxRemoveStatusMessage = (PFWLXREMOVESTATUSMESSAGE)GetProcAddress(hGina, "WlxRemoveStatusMessage"); 900 if (!Functions->WlxRemoveStatusMessage) goto cleanup; 901 } 902 903 /* Provide some default functions */ 904 if (!Functions->WlxScreenSaverNotify) 905 Functions->WlxScreenSaverNotify = DefaultWlxScreenSaverNotify; 906 907 ret = TRUE; 908 909 cleanup: 910 if (!ret) 911 { 912 if (hGina) 913 FreeLibrary(hGina); 914 } 915 else 916 *GinaInstance = hGina; 917 return ret; 918 } 919 920 BOOL 921 GinaInit( 922 IN OUT PWLSESSION Session) 923 { 924 DWORD GinaDllVersion; 925 926 if (!LoadGina(&Session->Gina.Functions, &GinaDllVersion, &Session->Gina.hDllInstance)) 927 return FALSE; 928 929 Session->Gina.Context = NULL; 930 Session->Gina.Version = GinaDllVersion; 931 Session->Gina.UseCtrlAltDelete = FALSE; 932 Session->SuppressStatus = FALSE; 933 934 TRACE("Calling WlxInitialize(\"%S\")\n", Session->InteractiveWindowStationName); 935 return Session->Gina.Functions.WlxInitialize( 936 Session->InteractiveWindowStationName, 937 (HANDLE)Session, 938 NULL, 939 (PVOID)&FunctionTable, 940 &Session->Gina.Context); 941 } 942 943 BOOL 944 AddAceToWindowStation( 945 IN HWINSTA WinSta, 946 IN PSID Sid) 947 { 948 DWORD AclSize; 949 SECURITY_INFORMATION SecurityInformation; 950 PACL pDefaultAcl = NULL; 951 PSECURITY_DESCRIPTOR WinstaSd = NULL; 952 PACCESS_ALLOWED_ACE Ace = NULL; 953 BOOL Ret = FALSE; 954 955 /* Allocate space for an ACL */ 956 AclSize = sizeof(ACL) 957 + 2 * (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(Sid)); 958 pDefaultAcl = HeapAlloc(GetProcessHeap(), 0, AclSize); 959 if (!pDefaultAcl) 960 { 961 ERR("WL: HeapAlloc() failed\n"); 962 goto cleanup; 963 } 964 965 /* Initialize it */ 966 if (!InitializeAcl(pDefaultAcl, AclSize, ACL_REVISION)) 967 { 968 ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError()); 969 goto cleanup; 970 } 971 972 /* Initialize new security descriptor */ 973 WinstaSd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH); 974 if (!InitializeSecurityDescriptor(WinstaSd, SECURITY_DESCRIPTOR_REVISION)) 975 { 976 ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError()); 977 goto cleanup; 978 } 979 980 /* Allocate memory for access allowed ACE */ 981 Ace = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACCESS_ALLOWED_ACE)+ 982 GetLengthSid(Sid) - sizeof(DWORD)); 983 984 /* Create the first ACE for the window station */ 985 Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; 986 Ace->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; 987 Ace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(Sid) - sizeof(DWORD); 988 Ace->Mask = GENERIC_ACCESS; 989 990 /* Copy the sid */ 991 if (!CopySid(GetLengthSid(Sid), &Ace->SidStart, Sid)) 992 { 993 ERR("WL: CopySid() failed (error %lu)\n", GetLastError()); 994 goto cleanup; 995 } 996 997 /* Add the first ACE */ 998 if (!AddAce(pDefaultAcl, ACL_REVISION, MAXDWORD, (LPVOID)Ace, Ace->Header.AceSize)) 999 { 1000 ERR("WL: AddAce() failed (error %lu)\n", GetLastError()); 1001 goto cleanup; 1002 } 1003 1004 /* Add the second ACE to the end of ACL */ 1005 Ace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE; 1006 Ace->Mask = WINSTA_ALL; 1007 if (!AddAce(pDefaultAcl, ACL_REVISION, MAXDWORD, (LPVOID)Ace, Ace->Header.AceSize)) 1008 { 1009 ERR("WL: AddAce() failed (error %lu)\n", GetLastError()); 1010 goto cleanup; 1011 } 1012 1013 /* Add ACL to winsta's security descriptor */ 1014 if (!SetSecurityDescriptorDacl(WinstaSd, TRUE, pDefaultAcl, FALSE)) 1015 { 1016 ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError()); 1017 goto cleanup; 1018 } 1019 1020 /* Apply security to the window station */ 1021 SecurityInformation = DACL_SECURITY_INFORMATION; 1022 if (!SetUserObjectSecurity(WinSta, &SecurityInformation, WinstaSd)) 1023 { 1024 ERR("WL: SetUserObjectSecurity() failed (error %lu)\n", GetLastError()); 1025 goto cleanup; 1026 } 1027 1028 /* Indicate success */ 1029 Ret = TRUE; 1030 1031 cleanup: 1032 /* Free allocated stuff */ 1033 if (pDefaultAcl) HeapFree(GetProcessHeap(), 0, pDefaultAcl); 1034 if (WinstaSd) HeapFree(GetProcessHeap(), 0, WinstaSd); 1035 if (Ace) HeapFree(GetProcessHeap(), 0, Ace); 1036 1037 return Ret; 1038 } 1039 1040 BOOL 1041 AddAceToDesktop( 1042 IN HDESK Desktop, 1043 IN PSID WinlogonSid, 1044 IN PSID UserSid) 1045 { 1046 DWORD AclSize; 1047 SECURITY_INFORMATION SecurityInformation; 1048 PACL Acl = NULL; 1049 PSECURITY_DESCRIPTOR DesktopSd = NULL; 1050 BOOL Ret = FALSE; 1051 1052 /* Allocate ACL */ 1053 AclSize = sizeof(ACL) 1054 + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(WinlogonSid); 1055 1056 /* Take user's sid into account */ 1057 if (UserSid) 1058 AclSize += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(UserSid); 1059 1060 Acl = HeapAlloc(GetProcessHeap(), 0, AclSize); 1061 if (!Acl) 1062 { 1063 ERR("WL: HeapAlloc() failed\n"); 1064 goto cleanup; 1065 } 1066 1067 /* Initialize ACL */ 1068 if (!InitializeAcl(Acl, AclSize, ACL_REVISION)) 1069 { 1070 ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError()); 1071 goto cleanup; 1072 } 1073 1074 /* Add full desktop access ACE for winlogon */ 1075 if (!AddAccessAllowedAce(Acl, ACL_REVISION, DESKTOP_ALL, WinlogonSid)) 1076 { 1077 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError()); 1078 goto cleanup; 1079 } 1080 1081 /* Add full desktop access ACE for a user (if provided) */ 1082 if (UserSid && !AddAccessAllowedAce(Acl, ACL_REVISION, DESKTOP_ALL, UserSid)) 1083 { 1084 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError()); 1085 goto cleanup; 1086 } 1087 1088 /* Initialize new security descriptor */ 1089 DesktopSd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH); 1090 if (!InitializeSecurityDescriptor(DesktopSd, SECURITY_DESCRIPTOR_REVISION)) 1091 { 1092 ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError()); 1093 goto cleanup; 1094 } 1095 1096 /* Add ACL to the security descriptor */ 1097 if (!SetSecurityDescriptorDacl(DesktopSd, TRUE, Acl, FALSE)) 1098 { 1099 ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError()); 1100 goto cleanup; 1101 } 1102 1103 /* Apply security to the window station */ 1104 SecurityInformation = DACL_SECURITY_INFORMATION; 1105 if (!SetUserObjectSecurity(Desktop, &SecurityInformation, DesktopSd)) 1106 { 1107 ERR("WL: SetUserObjectSecurity() failed (error %lu)\n", GetLastError()); 1108 goto cleanup; 1109 } 1110 1111 /* Indicate success */ 1112 Ret = TRUE; 1113 1114 cleanup: 1115 /* Free allocated stuff */ 1116 if (Acl) HeapFree(GetProcessHeap(), 0, Acl); 1117 if (DesktopSd) HeapFree(GetProcessHeap(), 0, DesktopSd); 1118 1119 return Ret; 1120 } 1121 1122 BOOL 1123 CreateWindowStationAndDesktops( 1124 IN OUT PWLSESSION Session) 1125 { 1126 BYTE LocalSystemBuffer[SECURITY_MAX_SID_SIZE]; 1127 BYTE InteractiveBuffer[SECURITY_MAX_SID_SIZE]; 1128 PSID pLocalSystemSid = (PSID)&LocalSystemBuffer; 1129 PSID pInteractiveSid = (PSID)InteractiveBuffer; 1130 DWORD SidSize, AclSize; 1131 PACL pDefaultAcl = NULL; 1132 PACL pUserDesktopAcl = NULL; 1133 SECURITY_DESCRIPTOR DefaultSecurityDescriptor; 1134 SECURITY_ATTRIBUTES DefaultSecurity; 1135 SECURITY_DESCRIPTOR UserDesktopSecurityDescriptor; 1136 SECURITY_ATTRIBUTES UserDesktopSecurity; 1137 BOOL ret = FALSE; 1138 1139 /* 1140 * Prepare information for ACLs we will apply 1141 */ 1142 SidSize = SECURITY_MAX_SID_SIZE; 1143 if (!CreateWellKnownSid(WinLocalSystemSid, NULL, pLocalSystemSid, &SidSize)) 1144 { 1145 ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError()); 1146 goto cleanup; 1147 } 1148 SidSize = SECURITY_MAX_SID_SIZE; 1149 if (!CreateWellKnownSid(WinInteractiveSid, NULL, pInteractiveSid, &SidSize)) 1150 { 1151 ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError()); 1152 goto cleanup; 1153 } 1154 1155 AclSize = sizeof(ACL) 1156 + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(pLocalSystemSid) 1157 + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(pInteractiveSid); 1158 pDefaultAcl = HeapAlloc(GetProcessHeap(), 0, AclSize); 1159 pUserDesktopAcl = HeapAlloc(GetProcessHeap(), 0, AclSize); 1160 if (!pDefaultAcl || !pUserDesktopAcl) 1161 { 1162 ERR("WL: HeapAlloc() failed\n"); 1163 goto cleanup; 1164 } 1165 1166 if (!InitializeAcl(pDefaultAcl, AclSize, ACL_REVISION) 1167 || !InitializeAcl(pUserDesktopAcl, AclSize, ACL_REVISION)) 1168 { 1169 ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError()); 1170 goto cleanup; 1171 } 1172 1173 /* 1174 * Create default ACL (window station, winlogon desktop, screen saver desktop) 1175 */ 1176 if (!AddAccessAllowedAce(pDefaultAcl, ACL_REVISION, GENERIC_ALL, pLocalSystemSid) 1177 || !AddAccessAllowedAce(pDefaultAcl, ACL_REVISION, GENERIC_READ, pInteractiveSid)) 1178 { 1179 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError()); 1180 goto cleanup; 1181 } 1182 1183 /* 1184 * Create the default security descriptor 1185 */ 1186 if (!InitializeSecurityDescriptor(&DefaultSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) 1187 { 1188 ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError()); 1189 goto cleanup; 1190 } 1191 1192 if (!SetSecurityDescriptorDacl(&DefaultSecurityDescriptor, TRUE, pDefaultAcl, FALSE)) 1193 { 1194 ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError()); 1195 goto cleanup; 1196 } 1197 1198 DefaultSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); 1199 DefaultSecurity.lpSecurityDescriptor = &DefaultSecurityDescriptor; 1200 DefaultSecurity.bInheritHandle = TRUE; 1201 1202 /* 1203 * Create user desktop ACL 1204 */ 1205 if (!AddAccessAllowedAce(pUserDesktopAcl, ACL_REVISION, GENERIC_ALL, pLocalSystemSid) 1206 || !AddAccessAllowedAce(pUserDesktopAcl, ACL_REVISION, GENERIC_ALL, pInteractiveSid)) 1207 { 1208 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError()); 1209 goto cleanup; 1210 } 1211 1212 /* 1213 * Create the user desktop security descriptor 1214 */ 1215 if (!InitializeSecurityDescriptor(&UserDesktopSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) 1216 { 1217 ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError()); 1218 goto cleanup; 1219 } 1220 1221 if (!SetSecurityDescriptorDacl(&UserDesktopSecurityDescriptor, TRUE, pUserDesktopAcl, FALSE)) 1222 { 1223 ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError()); 1224 goto cleanup; 1225 } 1226 1227 UserDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); 1228 UserDesktopSecurity.lpSecurityDescriptor = &UserDesktopSecurityDescriptor; 1229 UserDesktopSecurity.bInheritHandle = TRUE; 1230 1231 /* 1232 * Create the interactive window station 1233 */ 1234 Session->InteractiveWindowStationName = L"WinSta0"; 1235 Session->InteractiveWindowStation = CreateWindowStationW( 1236 Session->InteractiveWindowStationName, 1237 0, 1238 MAXIMUM_ALLOWED, 1239 &DefaultSecurity); 1240 if (!Session->InteractiveWindowStation) 1241 { 1242 ERR("WL: Failed to create window station (%lu)\n", GetLastError()); 1243 goto cleanup; 1244 } 1245 if (!SetProcessWindowStation(Session->InteractiveWindowStation)) 1246 { 1247 ERR("WL: SetProcessWindowStation() failed (error %lu)\n", GetLastError()); 1248 goto cleanup; 1249 } 1250 1251 /* 1252 * Create the application desktop 1253 */ 1254 Session->ApplicationDesktop = CreateDesktopW( 1255 L"Default", 1256 NULL, 1257 NULL, 1258 0, /* FIXME: Add DF_ALLOWOTHERACCOUNTHOOK flag? */ 1259 MAXIMUM_ALLOWED, 1260 &UserDesktopSecurity); 1261 if (!Session->ApplicationDesktop) 1262 { 1263 ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError()); 1264 goto cleanup; 1265 } 1266 1267 /* 1268 * Create the winlogon desktop 1269 */ 1270 Session->WinlogonDesktop = CreateDesktopW( 1271 L"Winlogon", 1272 NULL, 1273 NULL, 1274 0, 1275 MAXIMUM_ALLOWED, 1276 &DefaultSecurity); 1277 if (!Session->WinlogonDesktop) 1278 { 1279 ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError()); 1280 goto cleanup; 1281 } 1282 1283 /* 1284 * Create the screen saver desktop 1285 */ 1286 Session->ScreenSaverDesktop = CreateDesktopW( 1287 L"Screen-Saver", 1288 NULL, 1289 NULL, 1290 0, 1291 MAXIMUM_ALLOWED, 1292 &DefaultSecurity); 1293 if(!Session->ScreenSaverDesktop) 1294 { 1295 ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError()); 1296 goto cleanup; 1297 } 1298 1299 /* 1300 * Switch to winlogon desktop 1301 */ 1302 if (!SetThreadDesktop(Session->WinlogonDesktop) || 1303 !SwitchDesktop(Session->WinlogonDesktop)) 1304 { 1305 ERR("WL: Cannot switch to Winlogon desktop (%lu)\n", GetLastError()); 1306 goto cleanup; 1307 } 1308 1309 ret = TRUE; 1310 1311 cleanup: 1312 if (!ret) 1313 { 1314 if (Session->ApplicationDesktop) 1315 { 1316 CloseDesktop(Session->ApplicationDesktop); 1317 Session->ApplicationDesktop = NULL; 1318 } 1319 if (Session->WinlogonDesktop) 1320 { 1321 CloseDesktop(Session->WinlogonDesktop); 1322 Session->WinlogonDesktop = NULL; 1323 } 1324 if (Session->ScreenSaverDesktop) 1325 { 1326 CloseDesktop(Session->ScreenSaverDesktop); 1327 Session->ScreenSaverDesktop = NULL; 1328 } 1329 if (Session->InteractiveWindowStation) 1330 { 1331 CloseWindowStation(Session->InteractiveWindowStation); 1332 Session->InteractiveWindowStation = NULL; 1333 } 1334 } 1335 HeapFree(GetProcessHeap(), 0, pDefaultAcl); 1336 HeapFree(GetProcessHeap(), 0, pUserDesktopAcl); 1337 return ret; 1338 } 1339