winlogon.c
来自「一个类似windows」· C语言 代码 · 共 998 行 · 第 1/2 页
C
998 行
/* $Id: winlogon.c 21392 2006-03-25 21:04:40Z fireball $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/winlogon/winlogon.c
* PURPOSE: Logon
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* Created 22/05/98
*/
/* INCLUDES *****************************************************************/
#include "winlogon.h"
#define NDEBUG
#include <debug.h>
#define SUPPORT_CONSOLESTART 1
#define START_LSASS 1
/* GLOBALS ******************************************************************/
BOOL
LoadGina(PMSGINAFUNCTIONS Functions, DWORD *DllVersion);
PWLSESSION
MsGinaInit(void);
void
SessionLoop(PWLSESSION Session);
BOOL
InitServices(void);
BOOL
WlxCreateWindowStationAndDesktops(PWLSESSION Session);
HINSTANCE hAppInstance;
PWLSESSION WLSession = NULL;
#if SUPPORT_CONSOLESTART
BOOL StartConsole = TRUE;
#endif
/* FUNCTIONS *****************************************************************/
static void
PrintString (WCHAR* fmt,...)
{
WCHAR buffer[512];
va_list ap;
va_start(ap, fmt);
wsprintf(buffer, fmt, ap);
va_end(ap);
OutputDebugString(buffer);
}
INT_PTR CALLBACK
ShutdownComputerProc (HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_BTNSHTDOWNCOMPUTER:
EndDialog(hwndDlg, IDC_BTNSHTDOWNCOMPUTER);
break;
}
break;
}
case WM_INITDIALOG:
{
RemoveMenu(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND);
SetFocus(GetDlgItem(hwndDlg, IDC_BTNSHTDOWNCOMPUTER));
break;
}
}
return FALSE;
}
static BOOLEAN
StartServices (VOID)
{
HANDLE ServicesInitEvent;
BOOLEAN Result;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
DWORD Count;
WCHAR ServiceString[] = L"services.exe";
/* Start the service control manager (services.exe) */
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = NULL;
StartupInfo.lpTitle = NULL;
StartupInfo.dwFlags = 0;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0;
#if 0
PrintString(L"WL: Creating new process - \"services.exe\".\n");
#endif
Result = CreateProcess(NULL,
ServiceString,
NULL,
NULL,
FALSE,
DETACHED_PROCESS,
NULL,
NULL,
&StartupInfo,
&ProcessInformation);
if (!Result)
{
PrintString(L"WL: Failed to execute services\n");
return FALSE;
}
/* wait for event creation (by SCM) for max. 20 seconds */
for (Count = 0; Count < 20; Count++)
{
Sleep(1000);
DPRINT("WL: Attempting to open event \"SvcctrlStartEvent_A3725DX\"\n");
ServicesInitEvent = OpenEvent(EVENT_ALL_ACCESS, //SYNCHRONIZE,
FALSE,
L"SvcctrlStartEvent_A3725DX");
if (ServicesInitEvent != NULL)
{
break;
}
}
if (ServicesInitEvent == NULL)
{
DPRINT1("WL: Failed to open event \"SvcctrlStartEvent_A3725DX\"\n");
return FALSE;
}
/* wait for event signalization */
DPRINT("WL: Waiting forever on event handle: %x\n", ServicesInitEvent);
WaitForSingleObject(ServicesInitEvent, INFINITE);
DPRINT("WL: Closing event object \"SvcctrlStartEvent_A3725DX\"\n");
CloseHandle(ServicesInitEvent);
DPRINT("WL: StartServices() Done.\n");
return TRUE;
}
#if START_LSASS
static BOOLEAN
StartLsass (VOID)
{
HANDLE LsassInitEvent;
BOOLEAN Result;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
WCHAR ServiceString[] = L"lsass.exe";
LsassInitEvent = CreateEvent(NULL,
TRUE,
FALSE,
L"\\SECURITY_SERVICES_STARTED");
if (LsassInitEvent == NULL)
{
DPRINT1("WL: Failed to create lsass notification event\n");
return(FALSE);
}
/* Start the local security authority subsystem (lsass.exe) */
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = NULL;
StartupInfo.lpTitle = NULL;
StartupInfo.dwFlags = 0;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0;
Result = CreateProcess(NULL,
ServiceString,
NULL,
NULL,
FALSE,
DETACHED_PROCESS,
NULL,
NULL,
&StartupInfo,
&ProcessInformation);
if (!Result)
{
DPRINT1("WL: Failed to execute lsass\n");
return(FALSE);
}
WaitForSingleObject(LsassInitEvent, INFINITE);
CloseHandle(LsassInitEvent);
return(TRUE);
}
#endif
static BOOLEAN
OpenRegistryKey (HKEY *WinLogonKey)
{
return ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\WinLogon",
0,
KEY_QUERY_VALUE,
WinLogonKey);
}
static BOOLEAN StartProcess(PWCHAR ValueName)
{
BOOL StartIt;
HKEY WinLogonKey;
DWORD Type;
DWORD Size;
DWORD StartValue;
StartIt = TRUE;
if (OpenRegistryKey(&WinLogonKey))
{
Size = sizeof(DWORD);
if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
ValueName,
NULL,
&Type,
(LPBYTE) &StartValue,
&Size))
{
if (REG_DWORD == Type)
{
StartIt = (0 != StartValue);
}
}
RegCloseKey(WinLogonKey);
}
return StartIt;
}
/*
static BOOL RestartShell(void)
{
HKEY WinLogonKey;
DWORD Type, Size, Value;
if(OpenRegistryKey(&WinLogonKey))
{
Size = sizeof(DWORD);
if(ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
L"AutoRestartShell",
NULL,
&Type,
(LPBYTE)&Value,
&Size))
{
if(Type == REG_DWORD)
{
RegCloseKey(WinLogonKey);
return (Value != 0);
}
}
RegCloseKey(WinLogonKey);
}
return FALSE;
}
*/
VOID STDCALL
RegisterHotKeys(VOID)
{
RegisterHotKey(NULL, 0, MOD_ALT | MOD_CONTROL, VK_DELETE);
}
VOID STDCALL
UnregisterHotKeys(VOID)
{
UnregisterHotKey(NULL, 0);
}
VOID STDCALL
HandleHotKey(MSG *Msg)
{
DPRINT1("HOTKEY: Got hot key (%d)\n", Msg->wParam);
/* CTRL-ALT-DEL */
if (Msg->wParam == 0)
{
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = NULL;
StartupInfo.lpTitle = NULL;
StartupInfo.dwFlags = 0;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0;
CreateProcessW(
L"taskmgr.exe",
NULL,
NULL,
NULL,
FALSE,
CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS,
NULL,
NULL,
&StartupInfo,
&ProcessInformation);
CloseHandle (ProcessInformation.hProcess);
CloseHandle (ProcessInformation.hThread);
}
}
#if SUPPORT_CONSOLESTART
static BOOL StartIntoGUI(VOID)
{
HKEY WinLogonKey;
DWORD Type, Size, Value;
if(OpenRegistryKey(&WinLogonKey))
{
Size = sizeof(DWORD);
if(ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
L"StartGUI",
NULL,
&Type,
(LPBYTE)&Value,
&Size))
{
if(Type == REG_DWORD)
{
RegCloseKey(WinLogonKey);
return (Value != 0);
}
}
RegCloseKey(WinLogonKey);
}
return FALSE;
}
static PWCHAR
GetUserInit (WCHAR *CommandLine)
{
HKEY WinLogonKey;
BOOL GotCommandLine;
DWORD Type;
DWORD Size;
WCHAR Shell[_MAX_PATH];
GotCommandLine = FALSE;
if (OpenRegistryKey(&WinLogonKey))
{
Size = MAX_PATH;
if (ERROR_SUCCESS == RegQueryValueEx(WinLogonKey,
L"UserInit",
NULL,
&Type,
(LPBYTE) Shell,
&Size))
{
if (REG_EXPAND_SZ == Type)
{
ExpandEnvironmentStrings(Shell, CommandLine, _MAX_PATH);
GotCommandLine = TRUE;
}
else if (REG_SZ == Type)
{
wcscpy(CommandLine, Shell);
GotCommandLine = TRUE;
}
}
RegCloseKey(WinLogonKey);
}
if (! GotCommandLine)
{
GetSystemDirectory(CommandLine, MAX_PATH - 15);
wcscat(CommandLine, L"\\userinit.exe");
}
return CommandLine;
}
static BOOL
DoLogonUser (PWCHAR Name,
PWCHAR Password)
{
PROCESS_INFORMATION ProcessInformation;
STARTUPINFO StartupInfo;
WCHAR CommandLine[MAX_PATH];
WCHAR CurrentDirectory[MAX_PATH];
PROFILEINFOW ProfileInfo;
BOOL Result;
LPVOID lpEnvironment = NULL;
MSG Msg;
Result = LogonUserW (Name,
NULL,
Password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&WLSession->UserToken);
if (!Result)
{
DPRINT1 ("WL: LogonUserW() failed\n");
RtlDestroyEnvironment (lpEnvironment);
return FALSE;
}
/* Load the user profile */
ProfileInfo.dwSize = sizeof(PROFILEINFOW);
ProfileInfo.dwFlags = 0;
ProfileInfo.lpUserName = Name;
ProfileInfo.lpProfilePath = NULL;
ProfileInfo.lpDefaultPath = NULL;
ProfileInfo.lpServerName = NULL;
ProfileInfo.lpPolicyPath = NULL;
ProfileInfo.hProfile = NULL;
if (!LoadUserProfileW (WLSession->UserToken,
&ProfileInfo))
{
DPRINT1 ("WL: LoadUserProfileW() failed\n");
CloseHandle (WLSession->UserToken);
RtlDestroyEnvironment (lpEnvironment);
return FALSE;
}
if (!CreateEnvironmentBlock (&lpEnvironment,
WLSession->UserToken,
TRUE))
{
DPRINT1("WL: CreateEnvironmentBlock() failed\n");
return FALSE;
}
if (ImpersonateLoggedOnUser(WLSession->UserToken))
{
UpdatePerUserSystemParameters(0, TRUE);
RevertToSelf();
}
GetWindowsDirectoryW (CurrentDirectory, MAX_PATH);
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = NULL;
StartupInfo.lpTitle = NULL;
StartupInfo.dwFlags = 0;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0;
Result = CreateProcessAsUserW (WLSession->UserToken,
NULL,
GetUserInit (CommandLine),
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT,
lpEnvironment,
CurrentDirectory,
&StartupInfo,
&ProcessInformation);
if (!Result)
{
DPRINT1("WL: Failed to execute user shell %s\n", CommandLine);
if (ImpersonateLoggedOnUser(WLSession->UserToken))
{
UpdatePerUserSystemParameters(0, FALSE);
RevertToSelf();
}
UnloadUserProfile (WLSession->UserToken,
ProfileInfo.hProfile);
CloseHandle (WLSession->UserToken);
DestroyEnvironmentBlock (lpEnvironment);
return FALSE;
}
RegisterHotKeys();
while (WaitForSingleObject (ProcessInformation.hProcess, 100) != WAIT_OBJECT_0)
{
if (PeekMessage(&Msg, 0, 0, 0, PM_REMOVE))
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?