Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenwinlogon.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Winlogon 00004 * FILE: base/system/winlogon/winlogon.c 00005 * PURPOSE: Logon 00006 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net) 00007 * Filip Navara 00008 * Hervé Poussineau (hpoussin@reactos.org) 00009 */ 00010 00011 /* INCLUDES *****************************************************************/ 00012 00013 #include "winlogon.h" 00014 00015 #include <wine/debug.h> 00016 00017 WINE_DEFAULT_DEBUG_CHANNEL(winlogon); 00018 00019 /* GLOBALS ******************************************************************/ 00020 00021 HINSTANCE hAppInstance; 00022 PWLSESSION WLSession = NULL; 00023 00024 /* FUNCTIONS *****************************************************************/ 00025 00026 static BOOL 00027 StartServicesManager(VOID) 00028 { 00029 STARTUPINFOW StartupInfo; 00030 PROCESS_INFORMATION ProcessInformation; 00031 LPCWSTR ServiceString = L"services.exe"; 00032 BOOL res; 00033 00034 /* Start the service control manager (services.exe) */ 00035 ZeroMemory(&StartupInfo, sizeof(STARTUPINFOW)); 00036 StartupInfo.cb = sizeof(StartupInfo); 00037 StartupInfo.lpReserved = NULL; 00038 StartupInfo.lpDesktop = NULL; 00039 StartupInfo.lpTitle = NULL; 00040 StartupInfo.dwFlags = 0; 00041 StartupInfo.cbReserved2 = 0; 00042 StartupInfo.lpReserved2 = 0; 00043 00044 TRACE("WL: Creating new process - %S\n", ServiceString); 00045 00046 res = CreateProcessW( 00047 ServiceString, 00048 NULL, 00049 NULL, 00050 NULL, 00051 FALSE, 00052 DETACHED_PROCESS, 00053 NULL, 00054 NULL, 00055 &StartupInfo, 00056 &ProcessInformation); 00057 if (!res) 00058 { 00059 ERR("WL: Failed to execute services (error %lu)\n", GetLastError()); 00060 return FALSE; 00061 } 00062 00063 TRACE("WL: Created new process - %S\n", ServiceString); 00064 00065 CloseHandle(ProcessInformation.hThread); 00066 CloseHandle(ProcessInformation.hProcess); 00067 00068 TRACE("WL: StartServicesManager() done.\n"); 00069 00070 return TRUE; 00071 } 00072 00073 00074 static BOOL 00075 StartLsass(VOID) 00076 { 00077 STARTUPINFOW StartupInfo; 00078 PROCESS_INFORMATION ProcessInformation; 00079 LPCWSTR ServiceString = L"lsass.exe"; 00080 BOOL res; 00081 00082 /* Start the local security authority subsystem (lsass.exe) */ 00083 ZeroMemory(&StartupInfo, sizeof(STARTUPINFOW)); 00084 StartupInfo.cb = sizeof(StartupInfo); 00085 StartupInfo.lpReserved = NULL; 00086 StartupInfo.lpDesktop = NULL; 00087 StartupInfo.lpTitle = NULL; 00088 StartupInfo.dwFlags = 0; 00089 StartupInfo.cbReserved2 = 0; 00090 StartupInfo.lpReserved2 = 0; 00091 00092 TRACE("WL: Creating new process - %S\n", ServiceString); 00093 00094 res = CreateProcessW( 00095 ServiceString, 00096 NULL, 00097 NULL, 00098 NULL, 00099 FALSE, 00100 DETACHED_PROCESS, 00101 NULL, 00102 NULL, 00103 &StartupInfo, 00104 &ProcessInformation); 00105 00106 TRACE("WL: Created new process - %S\n", ServiceString); 00107 00108 CloseHandle(ProcessInformation.hThread); 00109 CloseHandle(ProcessInformation.hProcess); 00110 00111 return res; 00112 } 00113 00114 00115 static VOID 00116 WaitForLsass(VOID) 00117 { 00118 HANDLE hEvent; 00119 DWORD dwError; 00120 00121 hEvent = CreateEventW(NULL, 00122 TRUE, 00123 FALSE, 00124 L"LSA_RPC_SERVER_ACTIVE"); 00125 if (hEvent == NULL) 00126 { 00127 dwError = GetLastError(); 00128 TRACE("WL: Failed to create the notication event (Error %lu)\n", dwError); 00129 00130 if (dwError == ERROR_ALREADY_EXISTS) 00131 { 00132 hEvent = OpenEventW(SYNCHRONIZE, 00133 FALSE, 00134 L"LSA_RPC_SERVER_ACTIVE"); 00135 if (hEvent == NULL) 00136 { 00137 ERR("WL: Could not open the notification event (Error %lu)\n", GetLastError()); 00138 return; 00139 } 00140 } 00141 } 00142 00143 TRACE("WL: Wait for the LSA server!\n"); 00144 WaitForSingleObject(hEvent, INFINITE); 00145 TRACE("WL: LSA server running!\n"); 00146 00147 CloseHandle(hEvent); 00148 } 00149 00150 00151 static BOOL 00152 InitKeyboardLayouts() 00153 { 00154 WCHAR wszKeyName[12], wszKLID[10]; 00155 DWORD dwSize = sizeof(wszKLID), dwType, i = 1; 00156 HKEY hKey; 00157 UINT Flags; 00158 BOOL bRet = FALSE; 00159 00160 /* Open registry key with preloaded layouts */ 00161 if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Keyboard Layout\\Preload", 0, KEY_READ, &hKey) == ERROR_SUCCESS) 00162 { 00163 while(TRUE) 00164 { 00165 /* Read values with integer names only */ 00166 swprintf(wszKeyName, L"%d", i++); 00167 if (RegQueryValueExW(hKey, wszKeyName, NULL, &dwType, (LPBYTE)wszKLID, &dwSize) != ERROR_SUCCESS) 00168 { 00169 /* There is no more entries */ 00170 break; 00171 } 00172 00173 /* Only REG_SZ values are valid */ 00174 if (dwType != REG_SZ) 00175 { 00176 ERR("Wrong type: %ws!\n", wszKLID); 00177 continue; 00178 } 00179 00180 /* Load keyboard layout with given locale id */ 00181 Flags = KLF_SUBSTITUTE_OK; 00182 if (i > 1) 00183 Flags |= KLF_NOTELLSHELL|KLF_REPLACELANG; 00184 else // First layout 00185 Flags |= KLF_ACTIVATE; // |0x40000000 00186 if (!LoadKeyboardLayoutW(wszKLID, Flags)) 00187 { 00188 ERR("LoadKeyboardLayoutW(%ws) failed!\n", wszKLID); 00189 continue; 00190 } 00191 else 00192 { 00193 /* We loaded at least one layout - success */ 00194 bRet = TRUE; 00195 } 00196 } 00197 00198 /* Close the key now */ 00199 RegCloseKey(hKey); 00200 } 00201 else 00202 WARN("RegOpenKeyExW(Keyboard Layout\\Preload) failed!\n"); 00203 00204 if (!bRet) 00205 { 00206 /* If we failed, load US keyboard layout */ 00207 if (LoadKeyboardLayoutW(L"00000409", 0x04090409)) 00208 bRet = TRUE; 00209 } 00210 00211 return bRet; 00212 } 00213 00214 00215 BOOL 00216 DisplayStatusMessage( 00217 IN PWLSESSION Session, 00218 IN HDESK hDesktop, 00219 IN UINT ResourceId) 00220 { 00221 WCHAR StatusMsg[MAX_PATH]; 00222 00223 if (Session->Gina.Version < WLX_VERSION_1_3) 00224 return TRUE; 00225 00226 if (Session->SuppressStatus) 00227 return TRUE; 00228 00229 if (LoadStringW(hAppInstance, ResourceId, StatusMsg, MAX_PATH) == 0) 00230 return FALSE; 00231 00232 return Session->Gina.Functions.WlxDisplayStatusMessage(Session->Gina.Context, hDesktop, 0, NULL, StatusMsg); 00233 } 00234 00235 BOOL 00236 RemoveStatusMessage( 00237 IN PWLSESSION Session) 00238 { 00239 if (Session->Gina.Version < WLX_VERSION_1_3) 00240 return TRUE; 00241 00242 return Session->Gina.Functions.WlxRemoveStatusMessage(Session->Gina.Context); 00243 } 00244 00245 static INT_PTR CALLBACK 00246 GinaLoadFailedWindowProc( 00247 IN HWND hwndDlg, 00248 IN UINT uMsg, 00249 IN WPARAM wParam, 00250 IN LPARAM lParam) 00251 { 00252 switch (uMsg) 00253 { 00254 case WM_COMMAND: 00255 { 00256 switch (LOWORD(wParam)) 00257 { 00258 case IDOK: 00259 EndDialog(hwndDlg, IDOK); 00260 return TRUE; 00261 } 00262 break; 00263 } 00264 case WM_INITDIALOG: 00265 { 00266 int len; 00267 WCHAR templateText[MAX_PATH], text[MAX_PATH]; 00268 00269 len = GetDlgItemTextW(hwndDlg, IDC_GINALOADFAILED, templateText, MAX_PATH); 00270 if (len) 00271 { 00272 wsprintfW(text, templateText, (LPWSTR)lParam); 00273 SetDlgItemTextW(hwndDlg, IDC_GINALOADFAILED, text); 00274 } 00275 SetFocus(GetDlgItem(hwndDlg, IDOK)); 00276 return TRUE; 00277 } 00278 case WM_CLOSE: 00279 { 00280 EndDialog(hwndDlg, IDCANCEL); 00281 return TRUE; 00282 } 00283 } 00284 00285 return FALSE; 00286 } 00287 00288 int WINAPI 00289 WinMain( 00290 IN HINSTANCE hInstance, 00291 IN HINSTANCE hPrevInstance, 00292 IN LPSTR lpCmdLine, 00293 IN int nShowCmd) 00294 { 00295 #if 0 00296 LSA_STRING ProcessName, PackageName; 00297 HANDLE LsaHandle; 00298 LSA_OPERATIONAL_MODE Mode; 00299 BOOLEAN Old; 00300 ULONG AuthenticationPackage; 00301 NTSTATUS Status; 00302 #endif 00303 ULONG HardErrorResponse; 00304 MSG Msg; 00305 00306 UNREFERENCED_PARAMETER(hPrevInstance); 00307 UNREFERENCED_PARAMETER(lpCmdLine); 00308 UNREFERENCED_PARAMETER(nShowCmd); 00309 00310 hAppInstance = hInstance; 00311 00312 if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE)) 00313 { 00314 ERR("WL: Could not register logon process\n"); 00315 NtShutdownSystem(ShutdownNoReboot); 00316 ExitProcess(0); 00317 } 00318 00319 WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), 0, sizeof(WLSESSION)); 00320 if (!WLSession) 00321 { 00322 ERR("WL: Could not allocate memory for winlogon instance\n"); 00323 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); 00324 ExitProcess(1); 00325 } 00326 ZeroMemory(WLSession, sizeof(WLSESSION)); 00327 WLSession->DialogTimeout = 120; /* 2 minutes */ 00328 00329 if (!CreateWindowStationAndDesktops(WLSession)) 00330 { 00331 ERR("WL: Could not create window station and desktops\n"); 00332 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); 00333 ExitProcess(1); 00334 } 00335 LockWorkstation(WLSession); 00336 00337 /* Load default keyboard layouts */ 00338 if (!InitKeyboardLayouts()) 00339 { 00340 ERR("WL: Could not preload keyboard layouts\n"); 00341 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); 00342 ExitProcess(1); 00343 } 00344 00345 if (!StartServicesManager()) 00346 { 00347 ERR("WL: Could not start services.exe\n"); 00348 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); 00349 ExitProcess(1); 00350 } 00351 00352 if (!StartLsass()) 00353 { 00354 ERR("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError()); 00355 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, OptionOk, &HardErrorResponse); 00356 ExitProcess(1); 00357 } 00358 00359 /* Load and initialize gina */ 00360 if (!GinaInit(WLSession)) 00361 { 00362 ERR("WL: Failed to initialize Gina\n"); 00363 DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), GetDesktopWindow(), GinaLoadFailedWindowProc, (LPARAM)L""); 00364 HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT); 00365 ExitProcess(1); 00366 } 00367 00368 DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP); 00369 00370 00371 /* Wait for the LSA server */ 00372 WaitForLsass(); 00373 00374 #if 0 00375 /* Connect to NetLogon service (lsass.exe) */ 00376 /* Real winlogon uses "Winlogon" */ 00377 RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"Winlogon"); 00378 Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode); 00379 if (Status == STATUS_PORT_CONNECTION_REFUSED) 00380 { 00381 /* Add the 'SeTcbPrivilege' privilege and try again */ 00382 Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, TRUE, &Old); 00383 if (!NT_SUCCESS(Status)) 00384 { 00385 ERR("RtlAdjustPrivilege() failed with error %lu\n", LsaNtStatusToWinError(Status)); 00386 return 1; 00387 } 00388 Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode); 00389 } 00390 if (!NT_SUCCESS(Status)) 00391 { 00392 ERR("LsaRegisterLogonProcess() failed with error %lu\n", LsaNtStatusToWinError(Status)); 00393 return 1; 00394 } 00395 00396 RtlInitUnicodeString((PUNICODE_STRING)&PackageName, MICROSOFT_KERBEROS_NAME_W); 00397 Status = LsaLookupAuthenticationPackage(LsaHandle, &PackageName, &AuthenticationPackage); 00398 if (!NT_SUCCESS(Status)) 00399 { 00400 ERR("LsaLookupAuthenticationPackage() failed with error %lu\n", LsaNtStatusToWinError(Status)); 00401 LsaDeregisterLogonProcess(LsaHandle); 00402 return 1; 00403 } 00404 #endif 00405 00406 /* Create a hidden window to get SAS notifications */ 00407 if (!InitializeSAS(WLSession)) 00408 { 00409 ERR("WL: Failed to initialize SAS\n"); 00410 ExitProcess(2); 00411 } 00412 00413 //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS); 00414 //DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGCOMPUTERSETTINGS); 00415 00416 /* Display logged out screen */ 00417 WLSession->LogonStatus = WKSTA_IS_LOGGED_OFF; 00418 RemoveStatusMessage(WLSession); 00419 00420 /* Check for pending setup */ 00421 if (GetSetupType() != 0) 00422 { 00423 TRACE("WL: Setup mode detected\n"); 00424 00425 /* Run setup and reboot when done */ 00426 SwitchDesktop(WLSession->ApplicationDesktop); 00427 RunSetup(); 00428 } 00429 else 00430 PostMessageW(WLSession->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_TIMEOUT, 0); 00431 00432 /* Tell kernel that CurrentControlSet is good (needed 00433 * to support Last good known configuration boot) */ 00434 NtInitializeRegistry(CM_BOOT_FLAG_ACCEPTED | 1); 00435 00436 /* Message loop for the SAS window */ 00437 while (GetMessageW(&Msg, WLSession->SASWindow, 0, 0)) 00438 { 00439 TranslateMessage(&Msg); 00440 DispatchMessageW(&Msg); 00441 } 00442 00443 /* We never go there */ 00444 00445 return 0; 00446 } Generated on Sun May 27 2012 04:18:59 for ReactOS by
1.7.6.1
|