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 typedef struct _DIALOG_LIST_ENTRY 16 { 17 LIST_ENTRY Entry; 18 HWND hWnd; 19 DLGPROC DlgProc; 20 LPARAM lParam; 21 } DIALOG_LIST_ENTRY, *PDIALOG_LIST_ENTRY; 22 23 /* GLOBALS ******************************************************************/ 24 25 //static UINT_PTR IdTimer; 26 static LIST_ENTRY DialogListHead; 27 28 /* FUNCTIONS ****************************************************************/ 29 30 VOID 31 InitDialogListHead(VOID) 32 { 33 InitializeListHead(&DialogListHead); 34 } 35 36 37 static 38 PDIALOG_LIST_ENTRY 39 AddDialogListEntry(VOID) 40 { 41 PDIALOG_LIST_ENTRY ListEntry; 42 43 ListEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DIALOG_LIST_ENTRY)); 44 if (ListEntry == NULL) 45 return NULL; 46 47 TRACE("Add entry %p\n", ListEntry); 48 49 InsertHeadList(&DialogListHead, 50 &ListEntry->Entry); 51 52 return ListEntry; 53 } 54 55 56 static 57 VOID 58 RemoveDialogListEntry(PDIALOG_LIST_ENTRY ListEntry) 59 { 60 TRACE("Remove entry %p\n", ListEntry); 61 62 RemoveEntryList(&ListEntry->Entry); 63 RtlFreeHeap(RtlGetProcessHeap(), 0, ListEntry); 64 } 65 66 67 static 68 PDIALOG_LIST_ENTRY 69 GetDialogListEntry(HWND hwndDlg) 70 { 71 PDIALOG_LIST_ENTRY Current; 72 PLIST_ENTRY ListEntry; 73 74 ListEntry = DialogListHead.Flink; 75 while (ListEntry != &DialogListHead) 76 { 77 Current = CONTAINING_RECORD(ListEntry, 78 DIALOG_LIST_ENTRY, 79 Entry); 80 if (Current->hWnd == hwndDlg) 81 { 82 TRACE("Found entry: %p\n", Current); 83 return Current; 84 } 85 86 ListEntry = ListEntry->Flink; 87 } 88 89 TRACE("Found no entry!\n"); 90 return NULL; 91 } 92 93 94 VOID 95 CloseAllDialogWindows(VOID) 96 { 97 PDIALOG_LIST_ENTRY Current; 98 PLIST_ENTRY ListEntry; 99 100 ListEntry = DialogListHead.Flink; 101 while (ListEntry != &DialogListHead) 102 { 103 Current = CONTAINING_RECORD(ListEntry, 104 DIALOG_LIST_ENTRY, 105 Entry); 106 107 PostMessage(Current->hWnd, WLX_WM_SAS, 0, 0); 108 109 ListEntry = ListEntry->Flink; 110 } 111 } 112 113 114 static 115 INT_PTR 116 CALLBACK 117 DefaultWlxWindowProc( 118 IN HWND hwndDlg, 119 IN UINT uMsg, 120 IN WPARAM wParam, 121 IN LPARAM lParam) 122 { 123 PDIALOG_LIST_ENTRY ListEntry; 124 INT_PTR ret; 125 126 if (uMsg == WM_INITDIALOG) 127 { 128 ListEntry = (PDIALOG_LIST_ENTRY)lParam; 129 130 TRACE("Set dialog handle: %p\n", hwndDlg); 131 ListEntry->hWnd = hwndDlg; 132 lParam = ListEntry->lParam; 133 // SetTopTimeout(hWnd); 134 } 135 else 136 { 137 ListEntry = GetDialogListEntry(hwndDlg); 138 if (ListEntry == NULL) 139 return FALSE; 140 } 141 142 if (uMsg == WLX_WM_SAS) 143 { 144 EndDialog(hwndDlg, WLX_DLG_SAS); 145 return 0; 146 } 147 148 ret = ListEntry->DlgProc(hwndDlg, uMsg, wParam, lParam); 149 150 return ret; 151 152 /* 153 if (uMsg == WM_TIMER && (UINT_PTR)wParam == IdTimer) 154 { 155 EndDialog(hwndDlg, -1); 156 KillTimer(hwndDlg, IdTimer); 157 return TRUE; 158 } 159 else if (uMsg == WM_INITDIALOG) 160 { 161 IdTimer = SetTimer(hwndDlg, 0, WLSession->DialogTimeout * 1000, NULL); 162 return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam); 163 } 164 else if (uMsg == WM_NCDESTROY) 165 { 166 BOOL ret; 167 ret = PreviousWindowProc(hwndDlg, uMsg, wParam, lParam); 168 PreviousWindowProc = NULL; 169 return ret; 170 } 171 else 172 { 173 return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam); 174 } 175 */ 176 } 177 178 /* 179 * @implemented 180 */ 181 VOID 182 WINAPI 183 WlxUseCtrlAltDel( 184 HANDLE hWlx) 185 { 186 ULONG_PTR OldValue; 187 188 TRACE("WlxUseCtrlAltDel()\n"); 189 190 WlxSetOption(hWlx, WLX_OPTION_USE_CTRL_ALT_DEL, TRUE, &OldValue); 191 } 192 193 /* 194 * @implemented 195 */ 196 VOID 197 WINAPI 198 WlxSetContextPointer( 199 HANDLE hWlx, 200 PVOID pWlxContext) 201 { 202 ULONG_PTR OldValue; 203 204 TRACE("WlxSetContextPointer(%p)\n", pWlxContext); 205 206 WlxSetOption(hWlx, WLX_OPTION_CONTEXT_POINTER, (ULONG_PTR)pWlxContext, &OldValue); 207 } 208 209 /* 210 * @implemented 211 */ 212 VOID 213 WINAPI 214 WlxSasNotify( 215 HANDLE hWlx, 216 DWORD dwSasType) 217 { 218 PWLSESSION Session = (PWLSESSION)hWlx; 219 220 TRACE("WlxSasNotify(0x%lx)\n", dwSasType); 221 222 if (dwSasType == WLX_SAS_TYPE_CTRL_ALT_DEL || dwSasType > WLX_SAS_TYPE_MAX_MSFT_VALUE) 223 PostMessageW(Session->SASWindow, WLX_WM_SAS, dwSasType, 0); 224 } 225 226 /* 227 * @implemented 228 */ 229 BOOL 230 WINAPI 231 WlxSetTimeout( 232 HANDLE hWlx, 233 DWORD Timeout) 234 { 235 PWLSESSION Session = (PWLSESSION)hWlx; 236 237 TRACE("WlxSetTimeout(%lu)\n", Timeout); 238 239 Session->DialogTimeout = Timeout; 240 return TRUE; 241 } 242 243 /* 244 * @unimplemented 245 */ 246 int 247 WINAPI 248 WlxAssignShellProtection( 249 HANDLE hWlx, 250 HANDLE hToken, 251 HANDLE hProcess, 252 HANDLE hThread) 253 { 254 UNREFERENCED_PARAMETER(hWlx); 255 UNREFERENCED_PARAMETER(hToken); 256 UNREFERENCED_PARAMETER(hProcess); 257 UNREFERENCED_PARAMETER(hThread); 258 259 UNIMPLEMENTED; 260 return 0; 261 } 262 263 /* 264 * @implemented 265 */ 266 int 267 WINAPI 268 WlxMessageBox( 269 HANDLE hWlx, 270 HWND hwndOwner, 271 LPWSTR lpszText, 272 LPWSTR lpszTitle, 273 UINT fuStyle) 274 { 275 UNREFERENCED_PARAMETER(hWlx); 276 277 TRACE("WlxMessageBox()\n"); 278 /* FIXME: Provide a custom window proc to be able to handle timeout */ 279 return MessageBoxW(hwndOwner, lpszText, lpszTitle, fuStyle); 280 } 281 282 /* 283 * @implemented 284 */ 285 int 286 WINAPI 287 WlxDialogBox( 288 HANDLE hWlx, 289 HANDLE hInst, 290 LPWSTR lpszTemplate, 291 HWND hwndOwner, 292 DLGPROC dlgprc) 293 { 294 UNREFERENCED_PARAMETER(hWlx); 295 296 TRACE("WlxDialogBox()\n"); 297 298 return (int)WlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner, dlgprc, 0); 299 } 300 301 /* 302 * @implemented 303 */ 304 int 305 WINAPI 306 WlxDialogBoxParam( 307 HANDLE hWlx, 308 HANDLE hInst, 309 LPWSTR lpszTemplate, 310 HWND hwndOwner, 311 DLGPROC dlgprc, 312 LPARAM dwInitParam) 313 { 314 PDIALOG_LIST_ENTRY ListEntry; 315 int ret; 316 317 UNREFERENCED_PARAMETER(hWlx); 318 319 TRACE("WlxDialogBoxParam()\n"); 320 321 ListEntry = AddDialogListEntry(); 322 if (ListEntry == NULL) 323 return -1; 324 325 ListEntry->DlgProc = dlgprc; 326 ListEntry->lParam = dwInitParam; 327 328 ret = (int)DialogBoxParamW(hInst, lpszTemplate, hwndOwner, DefaultWlxWindowProc, (LPARAM)ListEntry); 329 330 RemoveDialogListEntry(ListEntry); 331 332 return ret; 333 } 334 335 /* 336 * @implemented 337 */ 338 int 339 WINAPI 340 WlxDialogBoxIndirect( 341 HANDLE hWlx, 342 HANDLE hInst, 343 LPCDLGTEMPLATE hDialogTemplate, 344 HWND hwndOwner, 345 DLGPROC dlgprc) 346 { 347 UNREFERENCED_PARAMETER(hWlx); 348 349 TRACE("WlxDialogBoxIndirect()\n"); 350 351 return (int)WlxDialogBoxIndirectParam(hWlx, hInst, hDialogTemplate, hwndOwner, dlgprc, 0); 352 } 353 354 /* 355 * @implemented 356 */ 357 int 358 WINAPI 359 WlxDialogBoxIndirectParam( 360 HANDLE hWlx, 361 HANDLE hInst, 362 LPCDLGTEMPLATE hDialogTemplate, 363 HWND hwndOwner, 364 DLGPROC dlgprc, 365 LPARAM dwInitParam) 366 { 367 PDIALOG_LIST_ENTRY ListEntry; 368 int ret; 369 370 UNREFERENCED_PARAMETER(hWlx); 371 372 TRACE("WlxDialogBoxIndirectParam()\n"); 373 374 ListEntry = AddDialogListEntry(); 375 if (ListEntry == NULL) 376 return -1; 377 378 ListEntry->DlgProc = dlgprc; 379 ListEntry->lParam = dwInitParam; 380 381 ret = (int)DialogBoxIndirectParamW(hInst, hDialogTemplate, hwndOwner, DefaultWlxWindowProc, (LPARAM)ListEntry); 382 383 RemoveDialogListEntry(ListEntry); 384 385 return ret; 386 } 387 388 /* 389 * @implemented 390 */ 391 int 392 WINAPI 393 WlxSwitchDesktopToUser( 394 HANDLE hWlx) 395 { 396 PWLSESSION Session = (PWLSESSION)hWlx; 397 398 TRACE("WlxSwitchDesktopToUser()\n"); 399 400 return (int)SwitchDesktop(Session->ApplicationDesktop); 401 } 402 403 /* 404 * @implemented 405 */ 406 int 407 WINAPI 408 WlxSwitchDesktopToWinlogon( 409 HANDLE hWlx) 410 { 411 PWLSESSION Session = (PWLSESSION)hWlx; 412 413 TRACE("WlxSwitchDesktopToWinlogon()\n"); 414 415 return (int)SwitchDesktop(Session->WinlogonDesktop); 416 } 417 418 /* 419 * @unimplemented 420 */ 421 int 422 WINAPI 423 WlxChangePasswordNotify( 424 HANDLE hWlx, 425 PWLX_MPR_NOTIFY_INFO pMprInfo, 426 DWORD dwChangeInfo) 427 { 428 UNREFERENCED_PARAMETER(hWlx); 429 UNREFERENCED_PARAMETER(pMprInfo); 430 UNREFERENCED_PARAMETER(dwChangeInfo); 431 432 UNIMPLEMENTED; 433 return 0; 434 } 435 436 /* 437 * @unimplemented 438 */ 439 BOOL 440 WINAPI 441 WlxGetSourceDesktop( 442 HANDLE hWlx, 443 PWLX_DESKTOP* ppDesktop) 444 { 445 UNREFERENCED_PARAMETER(hWlx); 446 UNREFERENCED_PARAMETER(ppDesktop); 447 448 UNIMPLEMENTED; 449 return FALSE; 450 } 451 452 /* 453 * @unimplemented 454 */ 455 BOOL 456 WINAPI 457 WlxSetReturnDesktop( 458 HANDLE hWlx, 459 PWLX_DESKTOP pDesktop) 460 { 461 UNREFERENCED_PARAMETER(hWlx); 462 UNREFERENCED_PARAMETER(pDesktop); 463 464 UNIMPLEMENTED; 465 return FALSE; 466 } 467 468 /* 469 * @unimplemented 470 */ 471 BOOL 472 WINAPI 473 WlxCreateUserDesktop( 474 HANDLE hWlx, 475 HANDLE hToken, 476 DWORD Flags, 477 PWSTR pszDesktopName, 478 PWLX_DESKTOP* ppDesktop) 479 { 480 UNREFERENCED_PARAMETER(hWlx); 481 UNREFERENCED_PARAMETER(hToken); 482 UNREFERENCED_PARAMETER(Flags); 483 UNREFERENCED_PARAMETER(pszDesktopName); 484 UNREFERENCED_PARAMETER(ppDesktop); 485 486 UNIMPLEMENTED; 487 return FALSE; 488 } 489 490 /* 491 * @unimplemented 492 */ 493 int 494 WINAPI 495 WlxChangePasswordNotifyEx( 496 HANDLE hWlx, 497 PWLX_MPR_NOTIFY_INFO pMprInfo, 498 DWORD dwChangeInfo, 499 PWSTR ProviderName, 500 PVOID Reserved) 501 { 502 UNREFERENCED_PARAMETER(hWlx); 503 UNREFERENCED_PARAMETER(pMprInfo); 504 UNREFERENCED_PARAMETER(dwChangeInfo); 505 UNREFERENCED_PARAMETER(ProviderName); 506 UNREFERENCED_PARAMETER(Reserved); 507 508 UNIMPLEMENTED; 509 return 0; 510 } 511 512 /* 513 * @unimplemented 514 */ 515 BOOL 516 WINAPI 517 WlxCloseUserDesktop( 518 HANDLE hWlx, 519 PWLX_DESKTOP pDesktop, 520 HANDLE hToken) 521 { 522 UNREFERENCED_PARAMETER(hWlx); 523 UNREFERENCED_PARAMETER(pDesktop); 524 UNREFERENCED_PARAMETER(hToken); 525 526 UNIMPLEMENTED; 527 return FALSE; 528 } 529 530 /* 531 * @implemented 532 */ 533 BOOL 534 WINAPI 535 WlxSetOption( 536 HANDLE hWlx, 537 DWORD Option, 538 ULONG_PTR Value, 539 ULONG_PTR* OldValue) 540 { 541 PWLSESSION Session = (PWLSESSION)hWlx; 542 543 TRACE("WlxSetOption(%lu)\n", Option); 544 545 switch (Option) 546 { 547 case WLX_OPTION_USE_CTRL_ALT_DEL: 548 *OldValue = (ULONG_PTR)Session->Gina.UseCtrlAltDelete; 549 Session->Gina.UseCtrlAltDelete = (BOOL)Value; 550 return TRUE; 551 case WLX_OPTION_CONTEXT_POINTER: 552 *OldValue = (ULONG_PTR)Session->Gina.Context; 553 Session->Gina.Context = (PVOID)Value; 554 return TRUE; 555 case WLX_OPTION_USE_SMART_CARD: 556 UNIMPLEMENTED; 557 return FALSE; 558 } 559 560 return FALSE; 561 } 562 563 /* 564 * @implemented 565 */ 566 BOOL 567 WINAPI 568 WlxGetOption( 569 HANDLE hWlx, 570 DWORD Option, 571 ULONG_PTR* Value) 572 { 573 PWLSESSION Session = (PWLSESSION)hWlx; 574 575 TRACE("WlxGetOption(%lu)\n", Option); 576 577 switch (Option) 578 { 579 case WLX_OPTION_USE_CTRL_ALT_DEL: 580 *Value = (ULONG_PTR)Session->Gina.UseCtrlAltDelete; 581 return TRUE; 582 case WLX_OPTION_CONTEXT_POINTER: 583 { 584 *Value = (ULONG_PTR)Session->Gina.Context; 585 return TRUE; 586 } 587 case WLX_OPTION_USE_SMART_CARD: 588 case WLX_OPTION_SMART_CARD_PRESENT: 589 case WLX_OPTION_SMART_CARD_INFO: 590 UNIMPLEMENTED; 591 return FALSE; 592 case WLX_OPTION_DISPATCH_TABLE_SIZE: 593 { 594 switch (Session->Gina.Version) 595 { 596 case WLX_VERSION_1_0: 597 *Value = sizeof(WLX_DISPATCH_VERSION_1_0); 598 break; 599 case WLX_VERSION_1_1: 600 *Value = sizeof(WLX_DISPATCH_VERSION_1_1); 601 break; 602 case WLX_VERSION_1_2: 603 *Value = sizeof(WLX_DISPATCH_VERSION_1_2); 604 break; 605 case WLX_VERSION_1_3: 606 *Value = sizeof(WLX_DISPATCH_VERSION_1_3); 607 break; 608 case WLX_VERSION_1_4: 609 *Value = sizeof(WLX_DISPATCH_VERSION_1_4); 610 break; 611 default: 612 return FALSE; 613 } 614 return TRUE; 615 } 616 } 617 618 return FALSE; 619 } 620 621 /* 622 * @unimplemented 623 */ 624 VOID 625 WINAPI 626 WlxWin31Migrate( 627 HANDLE hWlx) 628 { 629 UNREFERENCED_PARAMETER(hWlx); 630 631 UNIMPLEMENTED; 632 } 633 634 /* 635 * @unimplemented 636 */ 637 BOOL 638 WINAPI 639 WlxQueryClientCredentials( 640 PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred) 641 { 642 UNREFERENCED_PARAMETER(pCred); 643 644 UNIMPLEMENTED; 645 return FALSE; 646 } 647 648 /* 649 * @unimplemented 650 */ 651 BOOL 652 WINAPI 653 WlxQueryInetConnectorCredentials( 654 PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred) 655 { 656 UNREFERENCED_PARAMETER(pCred); 657 658 UNIMPLEMENTED; 659 return FALSE; 660 } 661 662 /* 663 * @unimplemented 664 */ 665 BOOL 666 WINAPI 667 WlxDisconnect(VOID) 668 { 669 UNIMPLEMENTED; 670 return FALSE; 671 } 672 673 /* 674 * @unimplemented 675 */ 676 DWORD 677 WINAPI 678 WlxQueryTerminalServicesData( 679 HANDLE hWlx, 680 PWLX_TERMINAL_SERVICES_DATA pTSData, 681 WCHAR* UserName, 682 WCHAR* Domain) 683 { 684 UNREFERENCED_PARAMETER(hWlx); 685 UNREFERENCED_PARAMETER(pTSData); 686 UNREFERENCED_PARAMETER(UserName); 687 UNREFERENCED_PARAMETER(Domain); 688 689 UNIMPLEMENTED; 690 return 0; 691 } 692 693 /* 694 * @unimplemented 695 */ 696 DWORD 697 WINAPI 698 WlxQueryConsoleSwitchCredentials( 699 PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred) 700 { 701 UNREFERENCED_PARAMETER(pCred); 702 703 UNIMPLEMENTED; 704 return 0; 705 } 706 707 /* 708 * @unimplemented 709 */ 710 BOOL 711 WINAPI 712 WlxQueryTsLogonCredentials( 713 PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred) 714 { 715 UNREFERENCED_PARAMETER(pCred); 716 717 UNIMPLEMENTED; 718 return FALSE; 719 } 720 721 static 722 WLX_DISPATCH_VERSION_1_4 FunctionTable = { 723 WlxUseCtrlAltDel, 724 WlxSetContextPointer, 725 WlxSasNotify, 726 WlxSetTimeout, 727 WlxAssignShellProtection, 728 WlxMessageBox, 729 WlxDialogBox, 730 WlxDialogBoxParam, 731 WlxDialogBoxIndirect, 732 WlxDialogBoxIndirectParam, 733 WlxSwitchDesktopToUser, 734 WlxSwitchDesktopToWinlogon, 735 WlxChangePasswordNotify, 736 WlxGetSourceDesktop, 737 WlxSetReturnDesktop, 738 WlxCreateUserDesktop, 739 WlxChangePasswordNotifyEx, 740 WlxCloseUserDesktop, 741 WlxSetOption, 742 WlxGetOption, 743 WlxWin31Migrate, 744 WlxQueryClientCredentials, 745 WlxQueryInetConnectorCredentials, 746 WlxDisconnect, 747 WlxQueryTerminalServicesData, 748 WlxQueryConsoleSwitchCredentials, 749 WlxQueryTsLogonCredentials 750 }; 751 752 /******************************************************************************/ 753 754 static 755 BOOL 756 GetGinaPath( 757 OUT LPWSTR Path, 758 IN DWORD Len) 759 { 760 LONG Status; 761 DWORD Type, Size; 762 HKEY hKey; 763 764 Status = RegOpenKeyExW( 765 HKEY_LOCAL_MACHINE, 766 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 767 0, 768 KEY_QUERY_VALUE, 769 &hKey); 770 if (Status != ERROR_SUCCESS) 771 { 772 /* Default value */ 773 wcsncpy(Path, L"msgina.dll", Len); 774 return TRUE; 775 } 776 777 Size = Len * sizeof(WCHAR); 778 Status = RegQueryValueExW( 779 hKey, 780 L"GinaDLL", 781 NULL, 782 &Type, 783 (LPBYTE)Path, 784 &Size); 785 if (Status != ERROR_SUCCESS || Type != REG_SZ || Size == 0) 786 wcsncpy(Path, L"msgina.dll", Len); 787 RegCloseKey(hKey); 788 return TRUE; 789 } 790 791 static 792 BOOL 793 WINAPI 794 DefaultWlxScreenSaverNotify( 795 IN PVOID pWlxContext, 796 IN OUT BOOL *pSecure) 797 { 798 if (*pSecure) 799 *pSecure = WLSession->Gina.Functions.WlxIsLogoffOk(pWlxContext); 800 return TRUE; 801 } 802 803 static 804 BOOL 805 LoadGina( 806 IN OUT PGINAFUNCTIONS Functions, 807 OUT DWORD *DllVersion, 808 OUT HMODULE *GinaInstance) 809 { 810 HMODULE hGina = NULL; 811 WCHAR GinaDll[MAX_PATH + 1]; 812 BOOL ret = FALSE; 813 814 GinaDll[0] = '\0'; 815 if (!GetGinaPath(GinaDll, MAX_PATH)) 816 goto cleanup; 817 /* Terminate string */ 818 GinaDll[MAX_PATH] = '\0'; 819 820 hGina = LoadLibraryW(GinaDll); 821 if (!hGina) 822 goto cleanup; 823 824 Functions->WlxNegotiate = (PFWLXNEGOTIATE)GetProcAddress(hGina, "WlxNegotiate"); 825 Functions->WlxInitialize = (PFWLXINITIALIZE)GetProcAddress(hGina, "WlxInitialize"); 826 827 if (!Functions->WlxInitialize) 828 goto cleanup; 829 830 if (!Functions->WlxNegotiate) 831 { 832 /* Assume current version */ 833 *DllVersion = WLX_CURRENT_VERSION; 834 } 835 else 836 { 837 TRACE("About to negotiate with Gina %S. Winlogon uses version %x\n", 838 GinaDll, WLX_CURRENT_VERSION); 839 if (!Functions->WlxNegotiate(WLX_CURRENT_VERSION, DllVersion)) 840 goto cleanup; 841 } 842 843 TRACE("Gina uses WLX_VERSION %lx\n", *DllVersion); 844 845 if (*DllVersion >= WLX_VERSION_1_0) 846 { 847 Functions->WlxActivateUserShell = (PFWLXACTIVATEUSERSHELL)GetProcAddress(hGina, "WlxActivateUserShell"); 848 if (!Functions->WlxActivateUserShell) goto cleanup; 849 Functions->WlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hGina, "WlxDisplayLockedNotice"); 850 if (!Functions->WlxDisplayLockedNotice) goto cleanup; 851 Functions->WlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE)GetProcAddress(hGina, "WlxDisplaySASNotice"); 852 if (!Functions->WlxDisplaySASNotice) goto cleanup; 853 Functions->WlxIsLockOk = (PFWLXISLOCKOK)GetProcAddress(hGina, "WlxIsLockOk"); 854 if (!Functions->WlxIsLockOk) goto cleanup; 855 Functions->WlxIsLogoffOk = (PFWLXISLOGOFFOK)GetProcAddress(hGina, "WlxIsLogoffOk"); 856 if (!Functions->WlxIsLogoffOk) goto cleanup; 857 Functions->WlxLoggedOnSAS = (PFWLXLOGGEDONSAS)GetProcAddress(hGina, "WlxLoggedOnSAS"); 858 if (!Functions->WlxLoggedOnSAS) goto cleanup; 859 Functions->WlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS)GetProcAddress(hGina, "WlxLoggedOutSAS"); 860 if (!Functions->WlxLoggedOutSAS) goto cleanup; 861 Functions->WlxLogoff = (PFWLXLOGOFF)GetProcAddress(hGina, "WlxLogoff"); 862 if (!Functions->WlxLogoff) goto cleanup; 863 Functions->WlxShutdown = (PFWLXSHUTDOWN)GetProcAddress(hGina, "WlxShutdown"); 864 if (!Functions->WlxShutdown) goto cleanup; 865 Functions->WlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS)GetProcAddress(hGina, "WlxWkstaLockedSAS"); 866 if (!Functions->WlxWkstaLockedSAS) goto cleanup; 867 } 868 869 if (*DllVersion >= WLX_VERSION_1_1) 870 { 871 Functions->WlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY)GetProcAddress(hGina, "WlxScreenSaverNotify"); 872 Functions->WlxStartApplication = (PFWLXSTARTAPPLICATION)GetProcAddress(hGina, "WlxStartApplication"); 873 } 874 875 if (*DllVersion >= WLX_VERSION_1_3) 876 { 877 Functions->WlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE)GetProcAddress(hGina, "WlxDisplayStatusMessage"); 878 if (!Functions->WlxDisplayStatusMessage) goto cleanup; 879 Functions->WlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE)GetProcAddress(hGina, "WlxGetStatusMessage"); 880 if (!Functions->WlxGetStatusMessage) goto cleanup; 881 Functions->WlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD)GetProcAddress(hGina, "WlxNetworkProviderLoad"); 882 if (!Functions->WlxNetworkProviderLoad) goto cleanup; 883 Functions->WlxRemoveStatusMessage = (PFWLXREMOVESTATUSMESSAGE)GetProcAddress(hGina, "WlxRemoveStatusMessage"); 884 if (!Functions->WlxRemoveStatusMessage) goto cleanup; 885 } 886 887 /* Provide some default functions */ 888 if (!Functions->WlxScreenSaverNotify) 889 Functions->WlxScreenSaverNotify = DefaultWlxScreenSaverNotify; 890 891 ret = TRUE; 892 893 cleanup: 894 if (!ret) 895 { 896 if (hGina) 897 FreeLibrary(hGina); 898 } 899 else 900 *GinaInstance = hGina; 901 return ret; 902 } 903 904 BOOL 905 GinaInit( 906 IN OUT PWLSESSION Session) 907 { 908 DWORD GinaDllVersion; 909 910 if (!LoadGina(&Session->Gina.Functions, &GinaDllVersion, &Session->Gina.hDllInstance)) 911 return FALSE; 912 913 Session->Gina.Context = NULL; 914 Session->Gina.Version = GinaDllVersion; 915 Session->Gina.UseCtrlAltDelete = FALSE; 916 Session->SuppressStatus = FALSE; 917 918 TRACE("Calling WlxInitialize(\"%S\")\n", Session->InteractiveWindowStationName); 919 return Session->Gina.Functions.WlxInitialize( 920 Session->InteractiveWindowStationName, 921 (HANDLE)Session, 922 NULL, 923 (PVOID)&FunctionTable, 924 &Session->Gina.Context); 925 } 926 927 BOOL 928 CreateWindowStationAndDesktops( 929 _Inout_ PWLSESSION Session) 930 { 931 SECURITY_ATTRIBUTES WinstaSecurity; 932 SECURITY_ATTRIBUTES ApplicationDesktopSecurity; 933 SECURITY_ATTRIBUTES WinlogonDesktopSecurity; 934 SECURITY_ATTRIBUTES ScreenSaverDesktopSecurity; 935 PSECURITY_DESCRIPTOR WlWinstaSecurityDescriptor; 936 PSECURITY_DESCRIPTOR WlApplicationDesktopSecurityDescriptor; 937 PSECURITY_DESCRIPTOR WlWinlogonDesktopSecurityDescriptor; 938 PSECURITY_DESCRIPTOR WlScreenSaverDesktopSecurityDescriptor; 939 BOOL ret = FALSE; 940 941 if (!CreateWinstaSecurity(&WlWinstaSecurityDescriptor)) 942 { 943 ERR("WL: Failed to create winsta security!\n"); 944 return ret; 945 } 946 947 WinstaSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); 948 WinstaSecurity.lpSecurityDescriptor = WlWinstaSecurityDescriptor; 949 WinstaSecurity.bInheritHandle = TRUE; 950 951 if (!CreateApplicationDesktopSecurity(&WlApplicationDesktopSecurityDescriptor)) 952 { 953 ERR("WL: Failed to create application desktop security!\n"); 954 goto cleanup; 955 } 956 957 ApplicationDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); 958 ApplicationDesktopSecurity.lpSecurityDescriptor = WlApplicationDesktopSecurityDescriptor; 959 ApplicationDesktopSecurity.bInheritHandle = TRUE; 960 961 if (!CreateWinlogonDesktopSecurity(&WlWinlogonDesktopSecurityDescriptor)) 962 { 963 ERR("WL: Failed to create winlogon desktop security!\n"); 964 goto cleanup; 965 } 966 967 WinlogonDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); 968 WinlogonDesktopSecurity.lpSecurityDescriptor = WlWinlogonDesktopSecurityDescriptor; 969 WinlogonDesktopSecurity.bInheritHandle = FALSE; 970 971 if (!CreateScreenSaverSecurity(&WlScreenSaverDesktopSecurityDescriptor)) 972 { 973 ERR("WL: Failed to create winlogon desktop security!\n"); 974 goto cleanup; 975 } 976 977 ScreenSaverDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); 978 ScreenSaverDesktopSecurity.lpSecurityDescriptor = WlScreenSaverDesktopSecurityDescriptor; 979 ScreenSaverDesktopSecurity.bInheritHandle = TRUE; 980 981 /* 982 * Create the interactive window station 983 */ 984 Session->InteractiveWindowStationName = L"WinSta0"; 985 Session->InteractiveWindowStation = CreateWindowStationW( 986 Session->InteractiveWindowStationName, 987 0, 988 MAXIMUM_ALLOWED, 989 &WinstaSecurity); 990 if (!Session->InteractiveWindowStation) 991 { 992 ERR("WL: Failed to create window station (%lu)\n", GetLastError()); 993 goto cleanup; 994 } 995 996 if (!SetProcessWindowStation(Session->InteractiveWindowStation)) 997 { 998 ERR("WL: SetProcessWindowStation() failed (error %lu)\n", GetLastError()); 999 goto cleanup; 1000 } 1001 1002 /* 1003 * Create the application desktop 1004 */ 1005 Session->ApplicationDesktop = CreateDesktopW( 1006 L"Default", 1007 NULL, 1008 NULL, 1009 0, /* FIXME: Add DF_ALLOWOTHERACCOUNTHOOK flag? */ 1010 MAXIMUM_ALLOWED, 1011 &ApplicationDesktopSecurity); 1012 if (!Session->ApplicationDesktop) 1013 { 1014 ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError()); 1015 goto cleanup; 1016 } 1017 1018 /* 1019 * Create the winlogon desktop 1020 */ 1021 Session->WinlogonDesktop = CreateDesktopW( 1022 L"Winlogon", 1023 NULL, 1024 NULL, 1025 0, 1026 MAXIMUM_ALLOWED, 1027 &WinlogonDesktopSecurity); 1028 if (!Session->WinlogonDesktop) 1029 { 1030 ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError()); 1031 goto cleanup; 1032 } 1033 1034 /* 1035 * Create the screen saver desktop 1036 */ 1037 Session->ScreenSaverDesktop = CreateDesktopW( 1038 L"Screen-Saver", 1039 NULL, 1040 NULL, 1041 0, 1042 MAXIMUM_ALLOWED, 1043 &ScreenSaverDesktopSecurity); 1044 if(!Session->ScreenSaverDesktop) 1045 { 1046 ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError()); 1047 goto cleanup; 1048 } 1049 1050 /* 1051 * Switch to winlogon desktop 1052 */ 1053 if (!SetThreadDesktop(Session->WinlogonDesktop) || 1054 !SwitchDesktop(Session->WinlogonDesktop)) 1055 { 1056 ERR("WL: Cannot switch to Winlogon desktop (%lu)\n", GetLastError()); 1057 goto cleanup; 1058 } 1059 1060 SetWindowStationUser(Session->InteractiveWindowStation, 1061 &LuidNone, NULL, 0); 1062 1063 ret = TRUE; 1064 1065 cleanup: 1066 if (!ret) 1067 { 1068 if (Session->ApplicationDesktop) 1069 { 1070 CloseDesktop(Session->ApplicationDesktop); 1071 Session->ApplicationDesktop = NULL; 1072 } 1073 if (Session->WinlogonDesktop) 1074 { 1075 CloseDesktop(Session->WinlogonDesktop); 1076 Session->WinlogonDesktop = NULL; 1077 } 1078 if (Session->ScreenSaverDesktop) 1079 { 1080 CloseDesktop(Session->ScreenSaverDesktop); 1081 Session->ScreenSaverDesktop = NULL; 1082 } 1083 if (Session->InteractiveWindowStation) 1084 { 1085 CloseWindowStation(Session->InteractiveWindowStation); 1086 Session->InteractiveWindowStation = NULL; 1087 } 1088 if (WlWinstaSecurityDescriptor) 1089 { 1090 RtlFreeHeap(RtlGetProcessHeap(), 0, WlWinstaSecurityDescriptor); 1091 } 1092 if (WlApplicationDesktopSecurityDescriptor) 1093 { 1094 RtlFreeHeap(RtlGetProcessHeap(), 0, WlApplicationDesktopSecurityDescriptor); 1095 } 1096 if (WlWinlogonDesktopSecurityDescriptor) 1097 { 1098 RtlFreeHeap(RtlGetProcessHeap(), 0, WlWinlogonDesktopSecurityDescriptor); 1099 } 1100 if (WlScreenSaverDesktopSecurityDescriptor) 1101 { 1102 RtlFreeHeap(RtlGetProcessHeap(), 0, WlScreenSaverDesktopSecurityDescriptor); 1103 } 1104 } 1105 1106 return ret; 1107 } 1108